赞
踩
(1)对局双方各执一色棋子。
(2)空棋盘开局。
(3)黑先、白后,交替下子,每次只能下一子。
(4)棋子下在棋盘的空白点上,棋子下定后,不得向其它点移动,不得从棋盘上拿掉或拿起另落别处。
(5)黑方的第一枚棋子可下在棋盘任意交叉点上。
(6)轮流下子是双方的权利,但允许任何一方放弃下子权(即:PASS权)
//五子棋对局,执行黑方指定开局、三手可交换、五手两打的规定。整个对局过程中黑方有禁手,白方无禁手。
//黑方禁手有三三禁手、四四禁手和长连禁手三种。
#include<iostream>
#include<stdlib.h>
using namespace std;
#define X 15//棋盘大小
string qizi_1 = "X";//黑方
string qizi_2 = "O";//白方
string qipan[X*2+4][X*2+4];
int i = 0;//循环变量
int j = 0;//循环变量
void xian_shi_qi_pan()//显示棋盘 { for (j = 1; j <= X*2+2; j++) { for (i = 1; i <= X*2+2; i++) { cout << qipan[i][j]; } cout << endl; } } void fang_ge_qi_pang()//放个棋盘 { for (j = 1; j <= X * 2 + 2; j++) { for (i = 1; i <= X * 2 + 2; i++) { qipan[i][j] = " "; } } for (j = 1; j <= X * 2 + 2; j++)//棋盘初始化 { for (i = 1; i <= X * 2 + 2; i++) { if (j % 2 == 1&&j<=X*2+2&&i<=X*2) qipan[i][j] = "—"; if (i % 2 == 1 && j % 2 == 0&&i<=X*2+2&&j<=X*2+1) qipan[i][j] = "| "; } } xian_shi_qi_pan(); }
这里棋盘上不能只有棋子,要有格子,我使用了“|”和“—”,用Excel表格模拟应该是这样的:
![(https://img-blog.csdnimg.cn/9ca24d27062845bcbf1f617dc10a0e33.png?x-oss-process=image/watermark,type_ZHJvaWRzYW5zZmFsbGJhY2s,shadow_50,text_Q1NETiBA56CB5Luj56CB5L2_5oiR5b-r5LmQ,size_20,color_FFFFFF,t_70,g_se,x_16)
上面的格子,浅蓝色应该是“—”深蓝色应该是“|”,灰色的格子在最初应该是两个空格,同时在这个图右侧和下侧都没有封口,写函数的时候应该注意多一个if语句补上。
最终在黑框中的效果:
void fang_ge_qi_zi(int x0,int y0,string& qizi)//放置棋子
{
if (x0 == 0 && y0 == 0) return;//按照提示输入0 0 即此轮弃权,没有落子
qipan[x0][y0] = qizi + " ";
}
因为格子里是两个空格,只放棋子看起来棋子会偏向一侧,所以我微调了之前的空棋盘,把“|”改成了“| ”,然后把棋子后面加了个空格,保证了棋子在格子中间。
效果如图:
bool pan_duan_shu_yin(string& qizi)//输入棋子,判断此棋子持有方是否赢了 { for (i = 2; i <= X * 2; i += 2) { for (j = 2; j <= X * 2; j += 2) { if (qipan[i][j] == qipan[i + 2][j] && qipan[i][j] == qipan[i + 4][j] && qipan[i][j] == qipan[i + 6][j] && qipan[i][j] == qipan[i + 8][j] && qipan[i][j] == qizi+" ") return true; if (qipan[i][j] == qipan[i + 2][j] && qipan[i][j] == qipan[i + 4][j] && qipan[i][j] == qipan[i + 6][j] && qipan[i][j] == qipan[i + 8][j] && qipan[i][j] == qizi + " ") return true; if (qipan[i][j] == qipan[i + 2][j+2] && qipan[i][j] == qipan[i + 4][j+4] && qipan[i][j] == qipan[i + 6][j+6] && qipan[i][j] == qipan[i + 8][j+8] && qipan[i][j] == qizi + " ") return true; } } return false; }
暂时没想出更好的办法,如果要这样遍历完数组的话如果棋盘很大的话就慢了,现在是15*15暂时不用担心。这个方法应该也可以进一步精简,比如如果这个格子是空的就直接跳过。
bool shi_fou_you_xiao(int x, int y)//检查落子是否有效,有没有重叠,有没有落到棋盘外面
{
if (qipan[x][y] != " "&& !(x==0&&y==0))//要排除掉0 0 弃权的行为
{
cout << "你的落子无效" << endl;
return false;
}
if (x > X * 2+1 || x < 0 || y>X * 2+1 || y < 0)
{
cout << "你的落子在棋盘外" << endl;
return false;
}
return true;
}
int main() { int change = 1; while (change) { cout << "****************************************************************" << endl; cout << "**************请选择游戏****************************************" << endl; cout << "**************0.退出********************************************" << endl; cout << "**************1.电脑vs玩家**************************************" << endl; cout << "**************2.玩家vs玩家**************************************" << endl; cin >> change; switch (change) { case 1:break; case 2: { int x1, x2, y1, y2; fang_ge_qi_pang(); cout << "游戏开始!" << endl; do { cout << "请玩家1(黑子方)输入棋子坐标:(输入0 0即为此轮弃权没有落子)" << endl; cin >> x1 >> y1;//这个坐标是第x1行第y1列,所以下面对应的二维数组下标要反过来 while (!shi_fou_you_xiao(y1 * 2, x1 * 2))//判断落子是否有效 { cout << "请重新输入坐标:" << endl; cin >> x1 >> y1; } system("cls"); fang_ge_qi_zi(y1 * 2, x1 * 2, qizi_1); xian_shi_qi_pan(); if (pan_duan_shu_yin(qizi_1)) { cout << "游戏已结束,黑方胜" << endl; break;//下完就判断,如果胜负已定就不需要继续下了 } cout << "请玩家2(白子方)输入棋子坐标:(输入0 0即为此轮弃权没有落子)" << endl; cin >> x2 >> y2;//这个坐标是第x2行第y2列,所以下面对应的二维数组下标要反过来 while (!shi_fou_you_xiao(y2 * 2, x2 * 2)) { cout << "请重新输入坐标:" << endl; cin >> x2 >> y2; } system("cls"); fang_ge_qi_zi(y2 * 2, x2 * 2, qizi_2); xian_shi_qi_pan(); if (pan_duan_shu_yin(qizi_2)) { cout << "游戏已结束,白方胜" << endl; break;//下完就判断,如果胜负已定就不需要继续下了 } } while ((!pan_duan_shu_yin(qizi_1) == 1 || !pan_duan_shu_yin(qizi_2))); } case 0: break; } } system("pause"); return 0; }
这里只有玩家vs玩家,电脑怎么下还没想好……
全部代码如下:
//(1)对局双方各执一色棋子。 //(2)空棋盘开局。 //(3)黑先、白后,交替下子,每次只能下一子。 //(4)棋子下在棋盘的空白点上,棋子下定后,不得向其它点移动,不得从棋盘上拿掉或拿起另落别处。 //(5)黑方的第一枚棋子可下在棋盘任意交叉点上。 //(6)轮流下子是双方的权利,但允许任何一方放弃下子权(即:PASS权) //五子棋对局,执行黑方指定开局、三手可交换、五手两打的规定。整个对局过程中黑方有禁手,白方无禁手。 //黑方禁手有三三禁手、四四禁手和长连禁手三种。 #include<iostream> #include<stdlib.h> using namespace std; #define X 16 string qizi_1 = "X";//黑方 string qizi_2 = "O";//白方 string qipan[X*2+4][X*2+4]; int i = 0; int j = 0; void xian_shi_qi_pan() { for (j = 1; j <= X*2+2; j++) { for (i = 1; i <= X*2+2; i++) { cout << qipan[i][j]; } cout << endl; } } void fang_ge_qi_pang()//放个棋盘 { for (j = 1; j <= X * 2 + 2; j++) { for (i = 1; i <= X * 2 + 2; i++) { qipan[i][j] = " "; } } for (j = 1; j <= X * 2 + 2; j++)//棋盘初始化 { for (i = 1; i <= X * 2 + 2; i++) { if (j % 2 == 1&&j<=X*2+2&&i<=X*2) qipan[i][j] = "—"; if (i % 2 == 1 && j % 2 == 0&&i<=X*2+2&&j<=X*2+1) qipan[i][j] = "| "; } } xian_shi_qi_pan(); } void fang_ge_qi_zi(int x0,int y0,string& qizi)//放置棋子 { if (x0 == 0 && y0 == 0) return;//按照提示输入0 0 即此轮弃权,没有落子 qipan[x0][y0] = qizi + " "; } bool pan_duan_shu_yin(string& qizi)//输入棋子,判断此棋子持有方是否赢了 { for (i = 2; i <= X * 2; i += 2) { for (j = 2; j <= X * 2; j += 2) { if (qipan[i][j] == qipan[i + 2][j] && qipan[i][j] == qipan[i + 4][j] && qipan[i][j] == qipan[i + 6][j] && qipan[i][j] == qipan[i + 8][j] && qipan[i][j] == qizi+" ") return true; if (qipan[i][j] == qipan[i + 2][j] && qipan[i][j] == qipan[i + 4][j] && qipan[i][j] == qipan[i + 6][j] && qipan[i][j] == qipan[i + 8][j] && qipan[i][j] == qizi + " ") return true; if (qipan[i][j] == qipan[i + 2][j+2] && qipan[i][j] == qipan[i + 4][j+4] && qipan[i][j] == qipan[i + 6][j+6] && qipan[i][j] == qipan[i + 8][j+8] && qipan[i][j] == qizi + " ") return true; } } return false; } bool shi_fou_you_xiao(int x, int y)//检查落子是否有效,有没有重叠,有没有落到棋盘外面 { if (qipan[x][y] != " "&& !(x==0&&y==0)) { cout << "你的落子无效" << endl; return false; } if (x > X * 2+1 || x < 0 || y>X * 2+1 || y < 0) { cout << "你的落子在棋盘外" << endl; return false; } return true; } int main() { int change = 1; while (change) { cout << "****************************************************************" << endl; cout << "**************请选择游戏****************************************" << endl; cout << "**************0.退出********************************************" << endl; cout << "**************1.电脑vs玩家**************************************" << endl; cout << "**************2.玩家vs玩家**************************************" << endl; cin >> change; switch (change) { case 1:break; case 2: { int x1, x2, y1, y2; fang_ge_qi_pang(); cout << "游戏开始!" << endl; do { cout << "请玩家1(黑子方)输入棋子坐标:(输入0 0即为此轮弃权没有落子)" << endl; cin >> x1 >> y1;//这个坐标是第x1行第y1列,所以下面对应的二维数组下标要反过来 while (!shi_fou_you_xiao(y1 * 2, x1 * 2))//判断落子是否有效 { cout << "请重新输入坐标:" << endl; cin >> x1 >> y1; } system("cls"); fang_ge_qi_zi(y1 * 2, x1 * 2, qizi_1); xian_shi_qi_pan(); if (pan_duan_shu_yin(qizi_1)) { cout << "游戏已结束,黑方胜" << endl; break;//下完就判断,如果胜负已定就不需要继续下了 } cout << "请玩家2(白子方)输入棋子坐标:(输入0 0即为此轮弃权没有落子)" << endl; cin >> x2 >> y2;//这个坐标是第x2行第y2列,所以下面对应的二维数组下标要反过来 while (!shi_fou_you_xiao(y2 * 2, x2 * 2)) { cout << "请重新输入坐标:" << endl; cin >> x2 >> y2; } system("cls"); fang_ge_qi_zi(y2 * 2, x2 * 2, qizi_2); xian_shi_qi_pan(); if (pan_duan_shu_yin(qizi_2)) { cout << "游戏已结束,白方胜" << endl; break;//下完就判断,如果胜负已定就不需要继续下了 } } while ((!pan_duan_shu_yin(qizi_1) == 1 || !pan_duan_shu_yin(qizi_2))); } case 0: break; } } system("pause"); return 0; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。