黑白棋,又叫反棋、奥赛罗棋、苹果棋或翻转棋。黑白棋在西方和日本很流行。游戏通过相互翻转对方的棋子,最后以棋盘上谁的棋子多来判断胜负。它的游戏规则简单,因此上手很容易,但是它的变化又非常复杂。有一种说法是:只需要几分钟学会它,却需要一生的时间去精通它。
黑白棋的棋盘是一个有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(其实谈不上智能啦,没写什么算法 知识单纯的随机而已 算法等有时间再写吧~)
//智能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;
}
}
}
}
以上方法在UpDate中调用即可 除此之外 棋盘的每个Cube上都有相同的脚本
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;
}
}
棋子上会有反转简本 用一个bool变量控制。
注:棋子的数组好像定义反了0.0 懒得去改了就这样吧~