当前位置:   article > 正文

C++编程练习——五子棋游戏_c++编程游戏五子棋程序

c++编程游戏五子棋程序

基本规则

(1)对局双方各执一色棋子。
(2)空棋盘开局。
(3)黑先、白后,交替下子,每次只能下一子。
(4)棋子下在棋盘的空白点上,棋子下定后,不得向其它点移动,不得从棋盘上拿掉或拿起另落别处。
(5)黑方的第一枚棋子可下在棋盘任意交叉点上。
(6)轮流下子是双方的权利,但允许任何一方放弃下子权(即:PASS权)
//五子棋对局,执行黑方指定开局、三手可交换、五手两打的规定。整个对局过程中黑方有禁手,白方无禁手。
//黑方禁手有三三禁手、四四禁手和长连禁手三种。

重点

  1. 先弄个棋盘,决定用string类数组。
  2. 一个用于落子的函数
  3. 一个显示棋盘目前状况的函数
  4. 一个判断输赢的函数
  5. 一个可以重复落子的结构,这里打算用while,后由于判断输赢的需要改成do while

基本准备

#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;//循环变量
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

棋盘

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();
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

这里棋盘上不能只有棋子,要有格子,我使用了“|”和“—”,用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 + " ";
}
  • 1
  • 2
  • 3
  • 4
  • 5

因为格子里是两个空格,只放棋子看起来棋子会偏向一侧,所以我微调了之前的空棋盘,把“|”改成了“| ”,然后把棋子后面加了个空格,保证了棋子在格子中间。
效果如图:
效果1

判断输赢

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;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

暂时没想出更好的办法,如果要这样遍历完数组的话如果棋盘很大的话就慢了,现在是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;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

主函数

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;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60

这里只有玩家vs玩家,电脑怎么下还没想好……

第一版 只有玩家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;
}


  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Monodyee/article/detail/336411?site
推荐阅读
相关标签
  

闽ICP备14008679号