Created
November 17, 2018 15:42
-
-
Save keidaroo/9ca902ac754260fd0a781c744dfe1289 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Collections; | |
using System.Collections.Generic; | |
using UnityEngine; | |
using UnityEngine.SceneManagement; | |
/* | |
RULE | |
map { | |
0 -> nothing | |
1 -> wall | |
2 -> goal | |
マップの上に行くほど添え字は小さく | |
upx ->指定した方向に動くブロック | |
downx -> 指定した方向と逆に動くブロック | |
} | |
*/ | |
[DefaultExecutionOrder (-3)] | |
public class automaticgenerator : MonoBehaviour { | |
//------------------変数-------------------------// | |
public int[, ] map = new int[50, 50]; //x座標、y座標 | |
bool[, ] confirmedBlock = new bool[50, 50]; //通ることが確定したブロック | |
public int upX, upY; | |
public int downX, downY; | |
public int atLeastWallNum; | |
public int edgeLength; //一辺の長 | |
public int rotateNumLimit; | |
public int startUpX, startDownX, startUpY, startDownY; | |
int cnt = 0; | |
public int previous = 0; //0は下向き、1は右向き、2は下向き、3は左向き | |
//-------------------------------------------------// | |
// Use this for initialization | |
public bool isCompeteMode; | |
public bool isTutorialMode; | |
public string mapCode; | |
bool isSafeToConfirm (int y, int x, int range, int movex, int movey) { | |
for (int i = 0; i < range; i++) //ゴールにたどり着くまで | |
{ | |
if (map[y + movey, x + movex] == 1 && confirmedBlock[y + movey, x + movex] == true) { | |
return false; | |
} | |
x += movex; | |
y += movey; | |
} | |
for (int i = 0; i < range; i++) { | |
map[y, x] = 0; | |
confirmedBlock[y, x] = true; | |
x -= movex; | |
y -= movey; | |
} | |
return true; | |
} | |
struct PairWithDirection { | |
public int x, y, beforeDirection, count; | |
public string beforePos; | |
}; | |
PairWithDirection moveToWall (int dir, PairWithDirection now) { | |
int[] xy = { 0, 1, 0, -1, 0 }; | |
while (true) { | |
if (map[now.y + xy[dir + 1], now.x + xy[dir]] != 1) { | |
now.x += xy[dir]; | |
now.y += xy[dir + 1]; | |
} else { | |
return now; | |
} | |
} | |
} | |
int conv (PairWithDirection toRed, PairWithDirection toBlue) { | |
string visCheck = '1' + toRed.x.ToString ().PadLeft (2, '0') + toRed.y.ToString ().PadLeft (2, '0') + toBlue.x.ToString ().PadLeft (2, '0') + toBlue.y.ToString ().PadLeft (2, '0'); | |
return int.Parse (visCheck); | |
} | |
public Dictionary<int, int> vis = new Dictionary<int, int> (); | |
int CountToGoal (PairWithDirection startBlue, PairWithDirection startRed) { | |
var blueQueue = new Queue<PairWithDirection> (); | |
var redQueue = new Queue<PairWithDirection> (); | |
blueQueue.Enqueue (startBlue); | |
redQueue.Enqueue (startRed); | |
int finalCnt = -1; | |
while (blueQueue.Count > 0) { | |
PairWithDirection blue = blueQueue.Dequeue (); | |
PairWithDirection red = redQueue.Dequeue (); | |
if (map[blue.y, blue.x] == 2 && map[red.y, red.x] == 2) { | |
finalCnt = blue.count; | |
break; | |
} | |
for (int toDirection = 0; toDirection < 4; toDirection++) { | |
if (red.beforeDirection == toDirection) { | |
continue; | |
} | |
var toRed = moveToWall (toDirection, red); | |
var toBlue = moveToWall ((toDirection + 2) % 4, blue); | |
string visCheck = '1' + toRed.x.ToString ().PadLeft (2, '0') + toRed.y.ToString ().PadLeft (2, '0') + toBlue.x.ToString ().PadLeft (2, '0') + toBlue.y.ToString ().PadLeft (2, '0'); | |
if (vis.ContainsKey (int.Parse (visCheck))) { continue; } | |
vis.Add (int.Parse (visCheck), conv (red, blue)); | |
visCheck = '1' + toBlue.x.ToString ().PadLeft (2, '0') + toBlue.y.ToString ().PadLeft (2, '0') + toRed.x.ToString ().PadLeft (2, '0') + toRed.y.ToString ().PadLeft (2, '0'); | |
vis.Add (int.Parse (visCheck), conv (blue, red)); | |
toRed.beforeDirection = toBlue.beforeDirection = (toDirection + 2) % 4; | |
toRed.count = toBlue.count = toRed.count + 1; | |
blueQueue.Enqueue (toBlue); | |
redQueue.Enqueue (toRed); | |
} | |
} | |
return finalCnt; | |
} | |
void Awake () { | |
Application.targetFrameRate = 60; //60FPSに設定 | |
if (isCompeteMode || isTutorialMode) { | |
map = GetComponent<codevisualizer> ().Lockoff (mapCode); | |
Debug.Log (map[0, 0]); | |
return; | |
} | |
int difficulty = GameObject.Find ("pointsText").GetComponent<data> ().difficulty; | |
if (difficulty == 0) { | |
upX = 7; | |
upY = 3; | |
downX = 5; | |
downY = 5; | |
atLeastWallNum = 10; | |
edgeLength = 10; | |
rotateNumLimit = 10; | |
} else if (difficulty == 1) { | |
upX = 9; | |
upY = 7; | |
downX = 7; | |
downY = 9; | |
atLeastWallNum = 40; | |
edgeLength = 16; | |
rotateNumLimit = 40; | |
} else if (difficulty == 2) { | |
upX = 13; | |
upY = 11; | |
downX = 11; | |
downY = 13; | |
atLeastWallNum = 80; | |
edgeLength = 24; | |
rotateNumLimit = 114514; | |
} else if (difficulty == 3) { | |
upX = 11; | |
upY = 9; | |
downX = 9; | |
downY = 11; | |
atLeastWallNum = 60; | |
edgeLength = 20; | |
rotateNumLimit = 114514; | |
} | |
map[downX, downY] = 0; | |
map[upX, upY] = 0; | |
startDownX = downX; | |
startDownY = downY; | |
startUpX = upX; | |
startUpY = upY; | |
//初期化 | |
for (int i = 0; i <= edgeLength; i++) { | |
for (int j = 0; j <= edgeLength; j++) { | |
confirmedBlock[i, j] = false; | |
map[i, j] = 0; | |
} | |
} | |
//初期のブロックの位置の上下にブロックを置く | |
for (int i = 0; i < 3; i++) //down | |
{ | |
map[upY - 1, upX - 1 + i] = 1; | |
confirmedBlock[upY - 1, upX - 1 + i] = true; | |
} | |
for (int i = 0; i < 3; i++) //up | |
{ | |
map[downY + 1, downX - 1 + i] = 1; | |
confirmedBlock[downY + 1, downX - 1 + i] = true; | |
} | |
for (int i = 0; i <= edgeLength; i++) { | |
map[0, i] = 1; | |
map[i, 0] = 1; | |
map[edgeLength, i] = 1; | |
map[i, edgeLength] = 1; | |
confirmedBlock[0, i] = true; | |
confirmedBlock[i, 0] = true; | |
confirmedBlock[edgeLength, i] = true; | |
confirmedBlock[i, edgeLength] = true; | |
} | |
for (int rotateNum = 0; rotateNum < rotateNumLimit; rotateNum++) { | |
int direction, range = 0, downrange = 0; | |
//重力通りに動く玉から | |
while (true) { | |
cnt++; | |
if (cnt > 9990) { break; } | |
//0は下向き、1は右向き、2は上向き、3は左向き | |
direction = Random.Range (0, 4); | |
if (direction == previous) { continue; } | |
if (direction == (previous + 2) % 4) { continue; } | |
if (direction == 0) //した | |
{ | |
range = Random.Range (0, edgeLength - 1 - upY); //壁を作る一歩手前で止まる | |
if (range % 2 == 1) { continue; } //もし距離が奇数なら | |
bool flag = false; | |
for (int i = 0; i < 3; i++) { | |
if (map[upY + range + 1, upX - 1 + i] == 0 && confirmedBlock[upY + range + 1, upX - 1 + i] == true) { | |
flag = true; | |
break; | |
} //三マス確認 | |
} | |
if (flag) { continue; } | |
if (!isSafeToConfirm (upY, upX, range, 0, 1)) { continue; } | |
for (int i = 0; i < 3; i++) { | |
map[upY + range + 1, upX - 1 + i] = 1; //三マス塗る! | |
confirmedBlock[upY + range + 1, upX - 1 + i] = true; | |
} | |
//----------------------------------------------// | |
upY += range; // | |
int count2 = 0; | |
while (true) // | |
{ | |
count2++; | |
if (count2 > 9999) { break; } | |
downrange = Random.Range (0, downY); | |
if (downrange % 2 == 1) { continue; } | |
flag = false; | |
for (int i = 0; i < 3; i++) { | |
if (map[downY - downrange - 1, downX - 1 + i] == 0 && confirmedBlock[downY - downrange - 1, downX - 1 + i] == true) { flag = true; break; } //三マス確認 | |
} | |
if (flag) { continue; } | |
if (!isSafeToConfirm (downY, downX, downrange, 0, -1)) { continue; } | |
for (int i = 0; i < 3; i++) { | |
map[downY - downrange - 1, downX - 1 + i] = 1; | |
confirmedBlock[downY - downrange - 1, downX - 1 + i] = true; | |
} | |
break; | |
} | |
//----------------------------------------------// | |
downY -= downrange; | |
} | |
if (direction == 1) { | |
range = Random.Range (0, edgeLength - 1 - upX); | |
if (range % 2 == 1) { continue; } | |
bool flag = false; | |
for (int i = 0; i < 3; i++) { | |
if (map[upY - 1 + i, upX + range + 1] == 0 && confirmedBlock[upY - 1 + i, upX + range + 1] == true) { flag = true; break; } //三マス確認 | |
} | |
if (flag) { continue; } | |
if (!isSafeToConfirm (upY, upX, range, 1, 0)) { continue; } | |
for (int i = 0; i < 3; i++) { | |
map[upY - 1 + i, upX + range + 1] = 1; | |
confirmedBlock[upY - 1 + i, upX + range + 1] = true; | |
} | |
//----------------------------------------------// | |
upX += range; | |
int count2 = 0; | |
while (true) { | |
count2++; | |
if (count2 > 9999) { break; } | |
downrange = Random.Range (0, downX); | |
if (downrange % 2 == 1) { continue; } | |
flag = false; | |
for (int i = 0; i < 3; i++) { | |
if (map[downY - 1 + i, downX - downrange - 1] == 0 && confirmedBlock[downY - 1 + i, downX - downrange - 1] == true) { flag = true; break; } //三マス確認 | |
} | |
if (flag) { continue; } | |
if (!isSafeToConfirm (downY, downX, downrange, -1, 0)) { continue; } | |
for (int i = 0; i < 3; i++) { | |
map[downY - 1 + i, downX - downrange - 1] = 1; | |
confirmedBlock[downY - 1 + i, downX - downrange - 1] = true; | |
} | |
break; | |
} | |
//----------------------------------------------// | |
downX -= downrange; | |
} | |
if (direction == 2) //上 | |
{ | |
range = Random.Range (0, upY); | |
if (range % 2 == 1) { continue; } | |
bool flag = false; | |
for (int i = 0; i < 3; i++) { | |
if (map[upY - range - 1, upX - 1 + i] == 0 && confirmedBlock[upY - range - 1, upX - 1 + i] == true) { flag = true; break; } //三マス確認 | |
} | |
if (flag) { continue; } | |
if (!isSafeToConfirm (upY, upX, range, 0, -1)) { continue; } | |
for (int i = 0; i < 3; i++) { | |
map[upY - range - 1, upX - 1 + i] = 1; | |
confirmedBlock[upY - range - 1, upX - 1 + i] = true; | |
} | |
//----------------------------------------------// | |
upY -= range; | |
int count2 = 0; | |
while (true) { | |
count2++; | |
if (count2 > 9999) { break; } | |
downrange = Random.Range (0, edgeLength - 1 - downY); //壁を作る一歩手前で止まる | |
if (downrange % 2 == 1) { continue; } //もし距離が奇数なら | |
flag = false; | |
for (int i = 0; i < 3; i++) { | |
if (map[downY + downrange + 1, downX - 1 + i] == 0 && confirmedBlock[downY + downrange + 1, downX - 1 + i] == true) { flag = true; break; } //三マス確認 | |
} | |
if (flag) { continue; } | |
if (!isSafeToConfirm (downY, downX, downrange, 0, 1)) { continue; } | |
for (int i = 0; i < 3; i++) { | |
map[downY + downrange + 1, downX - 1 + i] = 1; //三マス塗る! | |
confirmedBlock[downY + downrange + 1, downX - 1 + i] = true; // | |
} | |
break; | |
} | |
downY += downrange; | |
} | |
if (direction == 3) { | |
range = Random.Range (0, upX); | |
if (range % 2 == 1) { continue; } | |
bool flag = false; | |
for (int i = 0; i < 3; i++) { | |
if (map[upY - 1 + i, upX - range - 1] == 0 && confirmedBlock[upY - 1 + i, upX - range - 1] == true) { flag = true; break; } //三マス確認 | |
} | |
if (flag) { continue; } | |
if (!isSafeToConfirm (upY, upX, range, -1, 0)) { continue; } | |
for (int i = 0; i < 3; i++) { | |
map[upY - 1 + i, upX - range - 1] = 1; | |
confirmedBlock[upY - 1 + i, upX - range - 1] = true; | |
} | |
//----------------------------------------------// | |
upX -= range; | |
int count2 = 0; | |
while (true) { | |
count2++; | |
if (count2 > 9999) { break; } | |
downrange = Random.Range (0, edgeLength - 1 - downX); | |
if (downrange % 2 == 1) { continue; } | |
flag = false; | |
for (int i = 0; i < 3; i++) { | |
if (map[downY - 1 + i, downX + downrange + 1] == 0 && confirmedBlock[downY - 1 + i, downX + downrange + 1] == true) { flag = true; break; } //三マス確認 | |
} | |
if (flag) { continue; } | |
if (!isSafeToConfirm (downY, downX, downrange, 1, 0)) { continue; } | |
for (int i = 0; i < 3; i++) { | |
map[downY - 1 + i, downX + downrange + 1] = 1; | |
confirmedBlock[downY - 1 + i, downX + downrange + 1] = true; | |
} | |
break; | |
} | |
downX += downrange; | |
} | |
previous = direction; | |
break; | |
} | |
} | |
string scenename = SceneManager.GetActiveScene ().name; | |
if (upX == startUpX && upY == startUpY) { SceneManager.LoadScene (scenename); } | |
if (upX == startDownX && upY == startDownY) { SceneManager.LoadScene (scenename); } | |
if (downX == startUpX && downY == startUpY) { SceneManager.LoadScene (scenename); } | |
if (downX == startDownX && downY == startDownY) { SceneManager.LoadScene (scenename); } | |
confirmedBlock[startUpY, startUpX] = true; | |
confirmedBlock[startDownY, startDownX] = true; | |
int pikuto = 0; | |
for (int i = 1; i < edgeLength; i++) { | |
for (int j = 1; j < edgeLength; j++) { | |
if (map[i, j] == 1) { pikuto++; } | |
} | |
} | |
if (pikuto < atLeastWallNum) { SceneManager.LoadScene (scenename); } | |
map[upY, upX] = 2; | |
map[downY, downX] = 2; | |
PairWithDirection a = new PairWithDirection (), b = new PairWithDirection (); | |
a.x = startUpX; | |
a.y = startUpY; | |
b.x = startDownX; | |
b.y = startDownY; | |
b.beforeDirection = -1; | |
int countGoal = CountToGoal (a, b); | |
Debug.Log (countGoal); | |
if (difficulty == 0 && countGoal <= 1) { | |
SceneManager.LoadScene (scenename); | |
} else if (difficulty == 1 && countGoal <= 3) { | |
SceneManager.LoadScene (scenename); | |
} else if (difficulty == 3 && countGoal <= 4) { | |
SceneManager.LoadScene (scenename); | |
} else if (difficulty == 2 && countGoa l <= 4) { | |
SceneManager.LoadScene (scenename); | |
} | |
var movetheball = GameObject.Find ("playerObjectUp").GetComponent<movePlayer> (); | |
movetheball.goaldownX = downX; | |
movetheball.goaldownY = downY; | |
movetheball.goalupX = upX; | |
movetheball.goalupY = upY; | |
if (SceneManager.GetActiveScene ().name == "bot") { | |
GameObject.Find ("pointsText").GetComponent<data> ().botGameClear (); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment