黑白棋,又叫反棋、奥赛罗棋、苹果棋或翻转棋。黑白棋在西方和日本很流行。游戏通过相互翻转对方的棋子,最后以棋盘上谁的棋子多来判断胜负。它的游戏规则简单,因此上手很容易,但是它的变化又非常复杂。有一种说法是:只需要几分钟学会它,却需要一生的时间去精通它。
黑白棋的棋盘是一个有8*8方格的棋盘。下棋时将棋下在空格中间,而不是像围棋一样下在交叉点上。开始时在棋盘正中有两白两黑四个棋子交叉放置,黑棋总是先下子。把自己颜色的棋子放在棋盘的空格上,而当自己放下的棋子在横、竖、斜八个方向内有一个自己的棋子,则被夹在中间的全部翻转会成为自己的棋子。并且,只有在可以翻转棋子的地方才可以下子。
好了,知道了游戏规则我们如何去实现它呢?首先我们要去构建场景,也就是棋盘。我用64个Cube去创建(虽然很麻烦,但是可以控制Cube的高亮来提示玩家可以下的位置),一个Plane,以及四周的边框。棋子由两个Cylinder组成,一面黑一面白并设成预置物体。场景构建完毕,规则也了解了,接下来该实现了。首先要有一个虚拟棋盘去控制,我用了一个int型二维数组来表示,1表示黑棋 2表示白棋。一个gameobject型二维数组去存棋盘的64个Cube(实现提示),另一个gameobject型二维数组存棋子(控制反转)。高亮的棋盘玩家可以点击,没点击一次返回位置下的位置,在虚拟棋盘中去判断哪些棋子应该反转,之后更换玩家并在虚拟棋盘中计算可以下的位置,之后把这些Cube设成高亮,点击开关开启。这样循环下去,如果第一次没有找到可以下的位置,那么更换玩家,如果第二次没有找到则游戏结束,计算棋子数量决定胜负。
下面是初始化:
void Start () { numberChessBoard1 [4, 4] = 1; numberChessBoard1 [5, 5] = 1; numberChessBoard1 [4, 5] = 2; numberChessBoard1 [5, 4] = 2; gameObjectChessPiece [4, 4] = c1; gameObjectChessPiece [5, 5] = c2; gameObjectChessPiece [4, 5] = c3; gameObjectChessPiece [5, 4] = c4; GameObject[] a = GameObject.FindGameObjectsWithTag ("Cube"); for (int i = 0; i < 64; i++) { for (int j = 0; j < 64; j++) { Vector3 p = new Vector3 (-3.5f + (i / 8), -0.4f, 3.5f - (i % 8)); if (Vector3.Distance (a [j].transform.position, p) < 0.5f) { gameObjectChessBoard [i / 8 + 1, i % 8 + 1] = a [j]; } } } }玩家的变更以及胜利的判定
//玩家变更及胜利判定 void Win () { for (int k = 0; k < 3; k++) { alter++; //棋盘高亮 HighGreen (ref highGreen, numberChessBoard1, ref alter, player); if (alter == 1) { player = player % 2 + 1; GameObject.Find ("Text").GetComponent<GUIText>().text = "No way out,Players exchange"; } else if (alter == 2) { int player1 = 0; int player2 = 0; for (int i = 0; i < 9; i++) { for (int j = 0; j < 9; j++) { if (numberChessBoard1 [i, j] == 1) { player1++; } if (numberChessBoard1 [i, j] == 2) { player2++; } } } if (player1 > player2) { GameObject.Find ("Text").GetComponent<GUIText>().text = "Black:" + player1 + " White:" + player2 + " Winer is black"; } else if (player1 < player2) { GameObject.Find ("Text").GetComponent<GUIText>().text = "Black:" + player1 + " White:" + player2 + " Winer is white"; } else { GameObject.Find ("Text").GetComponent<GUIText>().text = "equalize the score"; } } else { break; } } }
//棋盘高亮 void HighGreen (ref int[,] highGreen, int[,] numberChessBoard1, ref int alter, int player) { for (int i = 1; i < 9; i++) { for (int j = 1; j < 9; j++) { if (numberChessBoard1 [i, j] == player) { //right for (int k = i - 1; k >= 1; k--) { if (numberChessBoard1 [k, j] == player) { break; } else if (numberChessBoard1 [k, j] == 0) { if (numberChessBoard1 [k + 1, j] == player % 2 + 1) { highGreen [k, j] = 1; alter = 0; } break; } } //left for (int k = i + 1; k <= 8; k++) { if (numberChessBoard1 [k, j] == player) { break; } else if (numberChessBoard1 [k, j] == 0) { if (numberChessBoard1 [k - 1, j] == player % 2 + 1) { highGreen [k, j] = 1; alter = 0; } break; } } //up for (int k = j + 1; k <= 8; k++) { if (numberChessBoard1 [i, k] == player) { break; } else if (numberChessBoard1 [i, k] == 0) { if (numberChessBoard1 [i, k - 1] == player % 2 + 1) { highGreen [i, k] = 1; alter = 0; } break; } } //down for (int k = j - 1; k >= 1; k--) { if (numberChessBoard1 [i, k] == player) { break; } else if (numberChessBoard1 [i, k] == 0) { if (numberChessBoard1 [i, k + 1] == player % 2 + 1) { highGreen [i, k] = 1; alter = 0; } break; } } //rightUp for (int k = i + 1; k <= 8; k++) { if (j - k + i <= 0 || j - k + i >= 9) { break; } if (numberChessBoard1 [k, j - k + i] == player) { break; } else if (numberChessBoard1 [k, j - k + i] == 0) { if (numberChessBoard1 [k - 1, j - k + i + 1] == player % 2 + 1) { highGreen [k, j - k + i] = 1; alter = 0; } break; } } //rightDown for (int k = i + 1; k <= 8; k++) { if (j - i + k <= 0 || j - i + k >= 9) { break; } if (numberChessBoard1 [k, j - i + k] == player) { break; } else if (numberChessBoard1 [k, j - i + k] == 0) { if (numberChessBoard1 [k - 1, j - i + k - 1] == player % 2 + 1) { highGreen [k, j - i + k] = 1; alter = 0; } break; } } //leftUp for (int k = i - 1; k > 0; k--) { if (j - i + k <= 0 || j - i + k >= 9) { break; } if (numberChessBoard1 [k, j - i + k] == player) { break; } else if (numberChessBoard1 [k, j - i + k] == 0) { if (numberChessBoard1 [k + 1, j - i + k + 1] == player % 2 + 1) { highGreen [k, j - i + k] = 1; alter = 0; } break; } } //leftUp for (int k = i - 1; k > 0; k--) { if (j - k + i <= 0 || j - k + i >= 9) { break; } if (numberChessBoard1 [k, j - k + i] == player) { break; } else if (numberChessBoard1 [k, j - k + i] == 0) { if (numberChessBoard1 [k + 1, j - k + i - 1] == player % 2 + 1) { highGreen [k, j - k + i] = 1; alter = 0; } break; } } } } } StartCoroutine ("ChessBoard"); } //高亮延迟 IEnumerator ChessBoard () { yield return new WaitForSeconds (0.6f); for (int i = 0; i < 9; i++) { for (int j = 0; j < 9; j++) { if (highGreen [i, j] == 1) { gameObjectChessBoard [i, j].GetComponent<Renderer> ().material = green; gameObjectChessBoard [i, j].GetComponent<Play> ().play = true; if (player != 2 || !ai) { highGreen [i, j] = 0; } } } } }
//智能AI IEnumerator AiPlay () { yield return new WaitForSeconds (0.5f); for (int i = 0; i < 9; i++) { for (int j = 0; j < 9; j++) { if (highGreen[i,j] == 1) { way.Add(i * 10 + j); } } } if (ai == true && player == 2) { int r = Random.Range(0,way.Count); gameObjectChessBoard [way[r] / 10,way[r] % 10].GetComponent<Play> ().aiPlay = true; m = way[r] / 10; n = way[r] % 10; way.Clear(); } for (int i = 0; i < 9; i++) { for (int j = 0; j < 9; j++) { highGreen [i, j] = 0; } } }
//更新虚拟棋盘 void Renovate () { for (int k = m - 1; k >= 1; k--) { if (numberChessBoard1 [k, n] == 0) { break; } else if (numberChessBoard1 [k, n] == player % 2 + 1) { if (numberChessBoard1 [k + 1, n] == player) { for (int i = k + 1; i < m; i++) { numberChessBoard1 [i, n] = player % 2 + 1; } } break; } } for (int k = m + 1; k <= 8; k++) { if (numberChessBoard1 [k, n] == 0) { break; } else if (numberChessBoard1 [k, n] == player % 2 + 1) { if (numberChessBoard1 [k - 1, n] == player) { for (int i = k - 1; i > m; i--) { numberChessBoard1 [i, n] = player % 2 + 1; } } break; } } for (int k = n + 1; k <= 8; k++) { if (numberChessBoard1 [m, k] == 0) { break; } else if (numberChessBoard1 [m, k] == player % 2 + 1) { if (numberChessBoard1 [m, k - 1] == player) { for (int i = k - 1; i > n; i--) { numberChessBoard1 [m, i] = player % 2 + 1; } } break; } } for (int k = n - 1; k >= 1; k--) { if (numberChessBoard1 [m, k] == 0) { break; } else if (numberChessBoard1 [m, k] == player % 2 + 1) { if (numberChessBoard1 [m, k + 1] == player) { for (int i = k + 1; i < n; i++) { numberChessBoard1 [m, i] = player % 2 + 1; } } break; } } for (int k = m + 1; k <= 8; k++) { if (n - k + m <= 0 || n - k + m >= 9) { break; } if (numberChessBoard1 [k, n - k + m] == 0) { break; } else if (numberChessBoard1 [k, n - k + m] == player % 2 + 1) { if (numberChessBoard1 [k - 1, n - k + m + 1] == player) { for (int i = k - 1; i > m; i--) { numberChessBoard1 [i, n - i + m] = player % 2 + 1; } } break; } } for (int k = m + 1; k <= 8; k++) { if (n - m + k <= 0 || n - m + k >= 9) { break; } if (numberChessBoard1 [k, n - m + k] == 0) { break; } else if (numberChessBoard1 [k, n - m + k] == player % 2 + 1) { if (numberChessBoard1 [k - 1, n - m + k - 1] == player) { for (int i = k - 1; i > m; i--) { numberChessBoard1 [i, n - m + i] = player % 2 + 1; } } break; } } for (int k = m - 1; k > 0; k--) { if (n - m + k <= 0 || n - m + k >= 9) { break; } if (numberChessBoard1 [k, n - m + k] == 0) { break; } else if (numberChessBoard1 [k, n - m + k] == player % 2 + 1) { if (numberChessBoard1 [k + 1, n - m + k + 1] == player) { for (int i = k + 1; i < m; i++) { numberChessBoard1 [i, n - m + i] = player % 2 + 1; } } break; } } for (int k = m - 1; k > 0; k--) { if (n - k + m <= 0 || n - k + m >= 9) { break; } if (numberChessBoard1 [k, n - k + m] == 0) { break; } else if (numberChessBoard1 [k, n - k + m] == player % 2 + 1) { if (numberChessBoard1 [k + 1, n - k + m - 1] == player) { for (int i = k + 1; i < m; i++) { numberChessBoard1 [i, n - i + m] = player % 2 + 1; } } break; } } }
//棋子翻转 void Flip () { for (int i = 0; i < 9; i++) { for (int j = 0; j < 9; j++) { if (gameObjectChessPiece [j, i] != null && ((numberChessBoard1 [i, j] - 1) * 180 - gameObjectChessPiece [j, i].transform.eulerAngles.z > -10 && (numberChessBoard1 [i, j] - 1) * 180 - gameObjectChessPiece [j, i].transform.eulerAngles.z < 10)) { gameObjectChessPiece [j, i].GetComponent<Flip> ().flip = true; } } } }
void Update () { player = GameObject.Find ("Script").GetComponent<BlackAndWhiteChess> ().player; gameObjectChessBoard = GameObject.Find ("Script").GetComponent<BlackAndWhiteChess> ().gameObjectChessBoard; if (aiPlay) { Playing (); aiPlay = false; } } void OnMouseDown() { if (play && !aiPlay) { Playing(); } } void Playing () { GameObject a = Instantiate(p,coordinate,Quaternion.Euler(180 * player,0,0)) as GameObject; GameObject.Find ("Script").GetComponent<BlackAndWhiteChess> ().gameObjectChessPiece[n,m] = a; for (int i = 1; i < 9; i++) { for (int j = 1; j < 9; j++) { gameObjectChessBoard[i,j].GetComponent<Renderer>().material = blackGreen; gameObjectChessBoard[i,j].GetComponent<Play>().play = false; } } GameObject.Find ("Text").GetComponent<GUIText>().text = ""; GameObject.Find ("Script").GetComponent<BlackAndWhiteChess> ().m = m; GameObject.Find ("Script").GetComponent<BlackAndWhiteChess> ().n = n; GameObject.Find ("Script").GetComponent<BlackAndWhiteChess> ().numberChessBoard1[m,n] = player; GameObject.Find ("Script").GetComponent<BlackAndWhiteChess> ().player = player % 2 + 1; GameObject.Find ("Script").GetComponent<BlackAndWhiteChess> ().play= true; } }
注:棋子的数组好像定义反了0.0 懒得去改了就这样吧~