-
-
Save swawa-yu/ed658257389b3d06d78d2e7e669f0d07 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 | |
|0 -> nothing | 1 -> wall | 2 -> goal | 3 -> answer| | |
|0 -> 下 | 1 -> 右 | 2 -> 上 | 3 -> 左| | |
map | |
-> x | |
↓ |0,0|1,0| | |
y |1,0|1,1| | |
upx ->指定した方向に動くブロック | |
downx -> 指定した方向と逆に動くブロック | |
*/ | |
[DefaultExecutionOrder(-3)] | |
public class automaticgenerator : MonoBehaviour { | |
//------------------変数-------------------------// | |
//SWAco:mapの要素へのアクセスは[x,y]で書いてます。元のソースコードはは[y,x]でした(?)。変更しきれてないとこがあるかもしれません | |
public MapChip[, ] map; //x座標、y座標 初期化は別のところで | |
public Cube up, down; | |
public Cube startUp, startDown; | |
public int atLeastWallNum; | |
public int edgeLength; //一辺の長 | |
public int rotateNumLimit; | |
//-------------------------------------------------// | |
// Use this for initialization | |
public bool isCompeteMode; | |
public bool isTutorialMode; | |
public string mapCode; | |
struct Cube { | |
public int X, Y; | |
public Type type; | |
public enum Type { | |
Up, | |
Down | |
} | |
public void Move(int add, Direction dir) { | |
if (type == Type.Down)add *= -1; | |
switch (dir) { | |
case Direction.Down: | |
Y += add; | |
break; | |
case Direction.Right: | |
X += add; | |
break; | |
case Direction.Up: | |
Y -= add; | |
break; | |
case Direction.Left: | |
X -= add; | |
break; | |
} | |
} | |
} | |
struct PairWithDirection { | |
public int x, y, beforeDirection, count; | |
public string beforePos; | |
}; | |
//mapの要素をintからenumにしました。一応暗黙の型変換ははたらくはずです | |
enum MapChip { | |
Nothing, | |
Wall, | |
Goal, | |
Answer | |
} | |
//方向もintからenumにしました。一応暗黙の型変換ははたらくはずです | |
enum Direction { | |
Down = 0, | |
Right, | |
Up, | |
Left | |
} | |
//SWAco:読んでません ここいじらないとバグでそうなのはしってるんですけど、、 | |
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]] != MapChip.Wall) { | |
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>(); | |
//SWAco:読んでません | |
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] == MapChip.Goal && map[red.y, red.x] == MapChip.Goal) { | |
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 InitParams(int upX, int upY, int downX, int downY, int atleastwallnum, int edgelength, int rotatenumlimit) { | |
up.X = upX; | |
up.Y = upY; | |
up.type = Cube.Type.Up; | |
down.X = downX; | |
down.Y = downY; | |
down.type = Cube.Type.Down; | |
atLeastWallNum = atleastwallnum; | |
edgeLength = edgelength; | |
rotateNumLimit = udrotatenumlimit; | |
map == new MapChip[edgelength, edgelength]; | |
} | |
void InitMap() { | |
for (int i = 0; i <= edgeLength; i++) { | |
for (int j = 0; j <= edgeLength; j++) { | |
map[i, j] = MapChip.Nothing; | |
} | |
} | |
map[down.X, down.Y] = MapChip.Answer; | |
map[up.X, up.Y] = MapChip.Answer; | |
//初期のブロックの位置の上下にブロックを置く | |
for (int i = 0; i < 3; i++) { | |
map[up.X - 1 + i, up.Y - 1] = MapChip.Wall; | |
map[down.X - 1 + i, down.Y + 1] = MapChip.Wall; | |
} | |
for (int i = 0; i <= edgeLength; i++) { | |
map[0, i] = MapChip.Wall; | |
map[i, 0] = MapChip.Wall; | |
map[edgeLength, i] = MapChip.Wall; | |
map[i, edgeLength] = MapChip.Wall; | |
} | |
} | |
//rangeが適切か(適切なら同時にAnswerで塗ります) | |
bool IsAppropriate(Cube cube, int range, Direction direction) { | |
if (range % 2 == 1)return false; //もし距離が奇数なら | |
//range先とその左右のマスに正解の道はないか | |
{ | |
int add = (range + 1) * (cube.type == Cube.Type.Up ? 1 : -1); | |
for (int i = 0; i < 3; i++) { | |
switch (dir) { | |
case Direction.Down: | |
if (map[cube.X - 1 + i, cube.Y + add] == MapChip.Answer)return false; | |
break; | |
case Direction.Right: | |
if (map[cube.X + add, cube.Y - 1 + i] == MapChip.Answer)return false; | |
break; | |
case Direction.Up: | |
if (map[cube.X - 1 + i, cube.Y - add] == MapChip.Answer)return false; | |
break; | |
case Direction.Left: | |
if (map[cube.X - add, cube.Y - 1 + i] == MapChip.Answer)return false; | |
break; | |
} | |
} | |
} | |
//isSafeToConfirm | |
{ | |
int x = cube.X, y = cube.Y; | |
int movex, movey; | |
switch (dir) { | |
case Direction.Down: | |
movex = 0; | |
movey = 1; | |
break; | |
case Direction.Right: | |
movex = 1; | |
movey = 0; | |
break; | |
case Direction.Up: | |
movex = 0; | |
movey = -1; | |
break; | |
case Direction.Left: | |
movex = -1; | |
movey = 0; | |
break; | |
} | |
if (type == Type.Down) { | |
movex *= -1; | |
movey *= -1; | |
} | |
//range進んで壁に当たらないか | |
for (int i = 0; i < range; i++, x += movex, y += movey) { | |
if (map[x + movex, y + movey] == MapChip.Wall)return false; | |
} | |
//元の場所まで戻りながらその道を答えの道に設定する | |
for (int i = 0; i < range; i++, x -= movex, y -= movey) { | |
map[x, y] = MapChip.Answer; | |
} | |
} | |
return true; | |
} | |
//SWAco:あいかわらず9990の正解が来るまでループするアルゴリズムのままです。どんなアルゴリズムにするかは任せます | |
void MakeWall(Cube cube, Direction direction) { | |
int add = cube.type == Cube.Type.Up ? 1 : -1; //もういっこ向こう側の列をいじるので | |
int range; | |
switch (direction) { | |
case Direction.Down: | |
//rangeを決定 | |
for (int i = 1; i <= 9990 && !IsAppropriate(cube, range, direction); i++) { | |
range = Random.Range(0, edgeLength - 1 - cube.Y); //壁を作る一歩手前まで | |
} | |
cube.Move(range, direction); | |
for (int i = 0; i < 3; i++)map[cube.X - 1 + i, cube.Y + add] = MapChip.Wall; //三マス塗る! | |
break; | |
case Direction.Right: | |
for (int i = 1; i <= 9990 && !IsAppropriate(cube, range, direction); i++) { | |
range = Random.Range(0, edgeLength - 1 - cube.Y); | |
} | |
cube.Move(range, direction); | |
for (int i = 0; i < 3; i++)map[cube.X + add, cube.Y - 1 + i] = MapChip.Wall; | |
break; | |
case Direction.Up: | |
for (int i = 1; i <= 9990 && !IsAppropriate(cube, range, direction); i++) { | |
range = Random.Range(0, edgeLength - 1 - cube.Y); | |
} | |
cube.Move(range, direction); | |
for (int i = 0; i < 3; i++)map[cube.X - 1 + i, cube.Y - add] = MapChip.Wall; | |
break; | |
case Direction.Left: | |
for (int i = 1; i <= 9990 && !IsAppropriate(cube, range, direction); i++) { | |
range = Random.Range(0, edgeLength - 1 - cube.Y); | |
} | |
cube.Move(range, direction); | |
for (int i = 0; i < 3; i++)map[cube.X - add, cube.Y - 1 + i] = MapChip.Wall; | |
break; | |
} | |
} | |
//SWAco:マップ生成と直接関わりのなさそうなところは読んでません | |
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)InitParams(7, 3, 5, 5, 10, 10, 10); | |
if (difficulty == 1)InitParams(9, 7, 7, 9, 40, 16, 40); | |
if (difficulty == 2)InitParams(13, 11, 11, 13, 80, 24, 114514); | |
if (difficulty == 3)InitParams(11, 9, 9, 11, 60, 20, 114514); | |
startDown = down; | |
startUp = up; | |
InitMap(); | |
Direction direction; | |
Direction previousDirection = Direction.Down; | |
for (int rotateNum = 0; rotateNum < rotateNumLimit; rotateNum++) { | |
direction = (previousDirection + 1) % 4; //前の方向から90度回転 | |
if (Random.Range(0, 2))direction = (direction + 2) % 4; //50%の確率でさらに方向を180度変える | |
MakeWall(up, direction); | |
MakeWall(down, direction); | |
previousDirection = direction; | |
} | |
string scenename = SceneManager.GetActiveScene().name; | |
if (up.X == startUp.X && up.Y == startUp.Y) { SceneManager.LoadScene(scenename); } | |
if (up.X == startDown.X && up.Y == startDown.Y) { SceneManager.LoadScene(scenename); } | |
if (down.X == startUp.X && down.Y == startUp.Y) { SceneManager.LoadScene(scenename); } | |
if (down.X == startDown.X && down.Y == startDown.Y) { SceneManager.LoadScene(scenename); } | |
int pikuto = 0; | |
for (int i = 1; i < edgeLength; i++) { | |
for (int j = 1; j < edgeLength; j++) { | |
if (map[i, j] == MapChip.Wall)pikuto++; | |
} | |
} | |
if (pikuto < atLeastWallNum) { SceneManager.LoadScene(scenename); } | |
map[up.X, up.Y] = MapChip.Goal; | |
map[down.X, down.Y] = MapChip.Goal; | |
PairWithDirection a = new PairWithDirection(), b = new PairWithDirection(); | |
a.x = startUp.X; | |
a.y = startUp.Y; | |
b.x = startDown.X; | |
b.y = startDown.Y; | |
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 && countGoal <= 4)SceneManager.LoadScene(scenename); | |
var movetheball = GameObject.Find("playerObjectUp").GetComponent<movePlayer>(); | |
movetheball.goaldownX = down.X; | |
movetheball.goaldownY = down.Y; | |
movetheball.goalupX = up.X; | |
movetheball.goalupY = up.Y; | |
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