人工智障三子棋

学习完数组和函数,我们就可以做一些比较有意思的事情了,比如篇文章所说的三子棋小游戏。

首先在开始写代码之前我们需要知道这个游戏所需要的内容有哪一些,划分模块。

  1.  游戏菜单
  2. 玩家如何选择游戏模式
  3. 游戏棋盘
  4. 玩家下棋的方法
  5. 电脑下棋的方法
  6. 如何判断输赢

接下来我们就来完善模块中的内容

1.游戏菜单

三子棋的游戏菜单很简单只需要1.开始游戏和2.结束游戏就可以了

void menu()
{
	printf("   1.开始游戏   ");
	printf("   0.结束游戏   ");
}

2.玩家如何选择游戏模式

  我们可以使用switch语句来根据玩家选择的值来进行不同的游戏模式

void test()
{
	int input = 0;
	do
	{
		menu();
		printf("请选择\n");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			game();
			break;
		case 0:
			printf("结束游戏\n");
			break;
		default:
			printf("选择错误\n");
			break;
		}
	} while (input);
}

3.游戏棋盘

 使用二维数组来存放下棋的棋子,根据三子棋游戏可以使用输出的方式打印出一个3×3棋盘,并且其中的内容都需要保存下来,据此可以使用一个3×3的数组来保存。

1)棋盘的初始化

void InitBoard(char Board[3][3], int row, int col)
{
	for (int i = 0; i < row; i++)
	{
		for (int j = 0; j < col; j++)
		{
			Board[i][j] = ' ';
		}
	}
}

2)棋盘的呈现:三子棋的棋盘是一个井字所以需要合理安排|符号和---符号才能正确的打印出来

void DiplayBoard(char Board[ROW][COL], int row, int col)
{
	for (int i = 0; i < row; i++)
	{
		for (int j = 0; j < col; j++)
		{
			printf(" %c ", Board[i][j]);
			if (j < col - 1)
			{
				printf("|");
			}
		}
		printf("\n");
		if (i < row - 1)
		{
			for (int j = 0; j < col; j++)
			{
				printf("---");
				if (j != col - 1)
				{
					printf("|");
				}
			}
			printf("\n");
		}
	}
}

4.玩家下棋的方法

落子前需要考虑的因素

1) 玩家不是程序员不知道数组从0开始,所以要稍微进行优化

2)落子前需要检测玩家输入的坐标是否合法

3)落子前玩家下的位置是否已经有棋子

下棋的方法即通过输入数组的元素来落子

Playmove(char Board[ROW][COL], int row, int col)
{
	int x = 0, y = 0;
	printf("请玩家下棋\n");
	while (1)
	{
		scanf("%d %d", &x, &y);
		if (x >= 1 && x <= row && y>=1 && y <= col)
		{
			if (Board[x - 1][y - 1] == ' ')
			{
				Board[x - 1][y - 1] = '*';
				break;
			}
			else
			{
				printf("该位置已经被占用\n");
			}

		}
		else
		{
			printf("输入错误\n");
		}

	}
}

5.电脑下棋的方法

我们这里采用的是一个人工智障的下棋方法 :即利用时间戳加以一定的处理使获得的数字在数组的范围之内即可。

void Computermove(char Board[ROW][COL], int row, int col)
{
	int x = 0;
	int y = 0;
	while (1)
	{
		x = rand() % row;
		y = rand() % col;
		if (Board[x - 1][y - 1] == ' ')
		{
			Board[x - 1][y - 1] = '#';
			break;
		}
	}
}

5,如何判断输赢

 三子棋赢的情况

1)一行有三个棋子连成线

2)一列有三个棋子连成线

3)对角线有三个棋子连成线

char is_win(char Board[ROW][COL], int row, int col)
{
	//判断行
	for (int i = 0; i < row; i++)
	{
		if (Board[i][0] == Board[i][1] && Board[i][1] == Board[i][2] && Board[i][1] != ' ')
		{
			return Board[i][1];
		}
	}
	//判断列
	for (int j = 0; j < col; j++)
	{
		if (Board[0][j] == Board[1][j] && Board[1][j] == Board[2][j] && Board[1][j] != ' ')
		{
			return Board[1][j];
		}
	}
	//判断对角线
	if (Board[0][0] == Board[1][1] && Board[1][1] == Board[2][2] && Board[1][1] != ' ')
	{
		return Board[1][1];
	}
	if (Board[0][2] == Board[1][1] && Board[1][1] == Board[2][0] && Board[1][1] != ' ')
	{
		return Board[1][1];
	}
	//平局
	if (is_full(Board,ROW,COL) == 1)
	{
		return 'Q';
	}
	//继续
	return 'C';
}

完整代码

test.c

#include"game.h"
void game()
{
	//存放下棋的数据
	char Board[ROW][COL] = { 0 };
	//初始化数组元素为空格
	InitBoard(Board, ROW, COL);
	//打印棋盘
	DiplayBoard(Board, ROW, COL);
	char ret;
	while (1)
	{
		//玩家下棋
		Playmove(Board, ROW, COL);
		DiplayBoard(Board, ROW, COL);
		ret = is_win(Board, ROW, COL);
		if (ret != 'C')
		{
			break;
		}
		//电脑下棋
		Computermove(Board, ROW, COL);
		DiplayBoard(Board, ROW, COL);
		is_win(Board, ROW, COL);
		ret = is_win(Board, ROW, COL);
		if (ret != 'C')
		{
			break;
		}
	}
	if (ret == '*')
	{
		printf("玩家赢\n");
	}
	else if (ret == '#')
	{
		printf("电脑赢\n");
	}
	else
	{
		printf("平局\n");
	}
	DiplayBoard(Board, ROW, COL);
}
void menu()
{
	printf("      1.开始游戏      \n");
	printf("      0.结束游戏      \n");
}
void test()
{
	int input = 0;
	srand((unsigned int)time(NULL));
	do
	{
		menu();
		printf("请选择\n");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			game();
			break;
		case 0:
			printf("结束游戏\n");
			break;
		default:
			printf("选择错误\n");
			break;
		}
	} while (input);
}
int main()
{
	test();
	return 0;
}

 

game.c

#include"game.h"

static int is_full(char Board[ROW][COL], int row, int col)
{
	for (int i = 0; i < row; i++)
	{
		for (int j = 0; j < col; j++)
		{
			if (Board[i][j] == ' ')
				return 0;
		}
	}
	return 1;
}
char is_win(char Board[ROW][COL], int row, int col)
{
	//判断行
	for (int i = 0; i < row; i++)
	{
		if (Board[i][0] == Board[i][1] && Board[i][1] == Board[i][2] && Board[i][1] != ' ')
		{
			return Board[i][1];
		}
	}
	//判断列
	for (int j = 0; j < col; j++)
	{
		if (Board[0][j] == Board[1][j] && Board[1][j] == Board[2][j] && Board[1][j] != ' ')
		{
			return Board[1][j];
		}
	}
	//判断对角线
	if (Board[0][0] == Board[1][1] && Board[1][1] == Board[2][2] && Board[1][1] != ' ')
	{
		return Board[1][1];
	}
	if (Board[0][2] == Board[1][1] && Board[1][1] == Board[2][0] && Board[1][1] != ' ')
	{
		return Board[1][1];
	}
	//平局
	if (is_full(Board,ROW,COL) == 1)
	{
		return 'Q';
	}
	//继续
	return 'C';
}
void Computermove(char Board[ROW][COL], int row, int col)
{
	int x = 0;
	int y = 0;
	while (1)
	{
		x = rand() % row;
		y = rand() % col;
		if (Board[x - 1][y - 1] == ' ')
		{
			Board[x - 1][y - 1] = '#';
			break;
		}
	}
}
void Playmove(char Board[ROW][COL], int row, int col)
{
	int x = 0, y = 0;
	printf("请玩家下棋\n");
	while (1)
	{
		scanf("%d %d", &x, &y);
		if (x >= 1 && x <= row && y>=1 && y <= col)
		{
			if (Board[x - 1][y - 1] == ' ')
			{
				Board[x - 1][y - 1] = '*';
				break;
			}
			else
			{
				printf("该位置已经被占用\n");
			}

		}
		else
		{
			printf("输入错误\n");
		}

	}
}
void InitBoard(char Board[3][3], int row, int col)
{
	for (int i = 0; i < row; i++)
	{
		for (int j = 0; j < col; j++)
		{
			Board[i][j] = ' ';
		}
	}
}
void DiplayBoard(char Board[ROW][COL], int row, int col)
{
	for (int i = 0; i < row; i++)
	{
		for (int j = 0; j < col; j++)
		{
			printf(" %c ", Board[i][j]);
			if (j < col - 1)
			{
				printf("|");
			}
		}
		printf("\n");
		if (i < row - 1)
		{
			for (int j = 0; j < col; j++)
			{
				printf("---");
				if (j != col - 1)
				{
					printf("|");
				}
			}
			printf("\n");
		}
	}
}

 

game.h

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define ROW 3
#define COL 3

//初始化棋盘
void InitBoard(char Board[ROW][COL],int row, int col);

//打印棋盘
void DiplayBoard(char Board[ROW][COL], int row, int col);

//玩家下棋
void Playmove(char Board[ROW][COL], int row, int col);

//电脑下棋
void Computermove(char Board[ROW][COL], int row, int col);

//判断输赢
char is_win(char Board[ROW][COL], int row, int col);

 

  在三子棋中主要是对数组的应用然后就是理清楚棋盘的逻辑和输赢的逻辑。弄清楚这些后就可以很简单的实现三子棋了 

上一篇:JavaSE面试题


下一篇:SpringMVC:上传与拦截器之一