三子棋代码教学

Posted Jack Chao

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了三子棋代码教学相关的知识,希望对你有一定的参考价值。

三子棋代码教学

三子棋算是比较早的益智互动游戏。那么我们怎么用C语言来解决呢?

这是利用代码之后的体现,我们在打代码之前,需要知道我们在游戏开始之前的界面长什么模样。那么我们在开始之前会有菜单函数来体现。
菜单函数

void menu()
{
	printf("**********************\\n");
	printf("*** 1:play  0:exit ***\\n");
	printf("**********************\\n");
}

这是个比较简单的函数体现。那么我们在结束之后,我们需要一个变量来获取使用者的一个选择。同时我们也需要利用这个变量来开始之后的决策。
首先,我们要判断用户的输入会有哪些情况。
第一种情况就是输入1,
第二种情况就是输入2,
第三种情况是为了防止程序出现bug而想到的,那就是,用户的输入不是1或者2.
这里我们很容易看出来,这是单一输入多元输出,我建议是使用switch()语句。同时我们需要把这个语句放到主函数当中。
代码如下

int main()
{
	int m = 0;
	srand((unsigned int)time(NULL));  //用于生成随机数,用于电脑下棋。我们先不管这个。
	do
	{
		menu();
		printf("请输入你的选择\\n");
		scanf("%d" , &m);
		switch(m)
		{
			case 1:
				game();  //用于游戏
				break;
			case 0:
				printf("退出游戏\\n");
				break;
			default:
				printf("输入错误字符\\n");
				break;
		}
	}while(m);
	return 0;
}

这个代码有这么几个重点需要知道,其一:我们运用的是do循环语句。这个语句的好处就是十分贴切switch语句。变量m既控制了用户输入,又控制着循环的开始和结束。case 1 , case 2 和default控制着我上面说的三种形式。那么到现在为止,我们很轻松的完成了这个函数的表面工作。
之后我们需要完成细节。
第一点,我们要学会制造棋盘。
棋盘代码


char board[row][col] = {0};  //定义棋盘的数组,因为三子棋是二维的,所以创建二维数组。

void dyboard(char board[row][col] ,int x,int y) //用于打印棋盘的函数
{
	int i = 0;   //控制行
	int j = 0;  //控制列
	for(i = 0;i < x;i++)     //第一个循环,是把三子棋的一行看作一个单元,然后进行复制性质的打印。
	{
		for(j = 0 ; j<y;j++)           //第二个循环,是把三子棋当中的一个个空格当作一个单元格进行复制打印。
		{
			printf(" %c " , board[i][j]);  //这边的打印同时也为了输入。可以让用户把想输入的位置输入正确的符号。
			if(j<y-1)
			{
				printf("|");     //这边一个判断是为了防止最后一个单元格也打印这个符号,我们可以清楚的发现最后一个单元格没有这个符号。
			}
		}
		printf("\\n");   //这边是打印好之后的回车,
		for(j = 0;j <y;j++)
		{
			printf("---");
			if(j<y-1)
			{
				printf("|");    //同上所述
			}
		}
		printf("\\n");
	}
}

在打印时我们发现,我们利用的是分割的思想,把一个大的工程,分割成一个个小的工程,然后进行复制打印。
那么棋盘打印好周,我们为了能玩好一遍之后还能再玩一遍,而不破坏棋盘时,我们可以初始化我们的棋盘。
初始化棋盘函数

void cshboard(char board[row][col] ,int x,int y)   //初始化棋盘函数 
{
	int i = 0;    //i和j控制着行和列。
	int j = 0;
	for(i = 0;i<x;i++)
	{
		for(j = 0 ; j < y ; j++)
		{
			board[i][j] = ' ';   //让board数组当中的每一个存储都变成空格
		}
	}
}

初始化棋盘之后我们就可以开始编写玩家该怎么进行游戏了。

玩家代码

void playermove(char board[row][col],int x,int y)  //玩家代码
{
	int ROW = 0;
	int COL = 0;
	while(1)
	{
		printf("玩家走\\n请输入坐标。\\n");  //玩家输入要下棋的位置
		scanf("%d %d" , &ROW , &COL);
		if(ROW>=1 && ROW<=x && COL>= 1 && COL<= y) //判断玩家下子的位置是否合法
		{
			if(board[ROW-1][COL-1] == ' ')  //判断玩家下子的位置,之前是不是有过棋子。
			{
				board[ROW-1][COL-1] = '*';  //如果下子的位置合法,就下。
				break;
			}
			else
			{
				printf("该坐标被占用\\n");
			}
		}
		else
		{
			printf("输入错误坐标。\\n");
		}
	}
}

在玩家下子的时候我们有很多的判断,是为了防止代码出现bug。当玩家输入之后,我们就轮到了,电脑下子。
电脑下子的程序

void computermove(char board[row][col],int x,int y)  //电脑下子的代码
{
	int ROW = 0;
	int COL = 0;
	printf("电脑走\\n");
	while(1)  //利用循环帮助,电脑下子。
	{
		ROW = rand()%row;    //为了实现电脑下子的位置都是合法的。rand()函数可以利用之前用到的srand()和time()函数来帮忙实现真正的随机。
		COL = rand()%col;
		if(board[ROW][COL] == ' ')  //判断电脑下子的位置是不是已经有棋子了。
		{
			board[ROW][COL] = '#';
			break;
		}
	}
}

在电脑下子的代码里我们也需要保证下子的合法性。
当玩家和电脑都下子之后,我们需要一个函数来判断输赢。
判断输赢的函数

char pdsy(char board[row][col],int x ,int y)
{
	int i = 0;    //i和j控制着行列
	int j = 0;
	for(i = 0;i<x;i++)
	{
		if(board[i][0] == board[i][1] && board[i][1] == board[i][2] && board[i][0] != ' ')  //判断是不是有行上相邻的三个棋子是相同的,如果是相同的就输出其中一个所代表的是什么图形,那么这个图形就获胜。
		{
			return board[i][0];
		}
	}
	for(j = 0;j<y;j++)
	{
		if(board[0][j] == board[1][j] && board[1][j] == board[2][j] && board[0][j] != ' ')  //判断列上相邻的是不是一样的,如果一样,就输出其中一个。那个输出的就是获胜的。
		{
			return board[0][j];
		}
	}
	if(board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[0][0] != ' ')  //判断斜方向上是不是有相同的
	{
		return board[1][1];
	}
	if(board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[0][2] != ' ')  //同样也是斜方向上的
	{
		return board[1][1];
	}
	if(1 == full(board,row,col))   //当以上几种都没有发生的时候,我们就只剩下两种情况,一种是还没下完,一种是打成平手。所以我们利用自定义函数full()来判断这个函数。
	{
		return 'p';  //当棋盘都满时,我们可以输出平
	}
	else
	{
		return 'c'; //当棋盘没满的时候,我们就输出继续。让电脑和玩家继续下。
	}
}



int full(char board[row][col],int x,int y)  //判断棋盘是不是下满了。
{
	int i = 0;
	int j = 0;
	for(i = 0;i < x;i++)
	{
		for(j = 0;j < y;j++)
		{
			if(board[i][j] == ' ') //判断是不是有空格。如果有就是没下满
			{
				return 0;
			}
		}
	}
	return 1;

当我们完成所有的一个个小部件之后我们就要组合一下。
组合代码

void game()
{
	char ret;    //用于存储判断输赢函数的输出结果
	char board[row][col] = {0};  //定义数组
	cshboard(board,row,col);  //初始化棋盘
	dyboard(board,row,col);   //打印棋盘函数
	while(1)   //利用循环,将游戏开始。while(1)。是为了保证循环一直继续,直到遇到break;
	{
		playermove(board,row,col);  //首先玩家先下棋
		dyboard(board,row,col);   //下好棋子之后我们要打印一遍棋盘,看棋子下在了哪里。
		ret = pdsy(board,row,col);   //判断我们下的子之后,会不会赢。
		if(ret != 'c')    //如果输出的不是C时,就结束循环,说明有结果了。
		{
			break;
		}
		computermove(board,row,col);   //电脑下棋,同上。
		dyboard(board,row,col);
		ret = pdsy(board,row,col);
		if(ret != 'c')
		{
			break;
		}
	}
	if(ret == '#')   //判断是谁获得胜利。
	{
		printf("电脑赢了!\\n");
	}
	else if(ret == '*')
	{
		printf("玩家赢了!\\n");
	}
	else if(ret == 'p')
	{
		printf("平局\\n");
	}
}

综上所述,所有函数就结合在了一起。三子棋也就出来。
接下来是完整代码
完整代码

//game.h 文件里的函数

#include<stdio.h>
#define row 3    //这是宏定义
#define col 3
void cshboard(char board[row][col] ,int x,int y);  //我们看到所有函数的定义之后都有board数组和x , y。因为我们所有的函数都是围绕着棋盘来进行的。x和y分别代表行和列。
void dyboard(char board[row][col] ,int x,int y);
void playermove(char board[row][col],int x,int y);
void computermove(char board[row][col],int x,int y);
char pdsy(char board[row][col],int x,int y);
int full(char board[row][col],int x,int y);



//game.c文件里的函数,这里有各种小函数。

#include"game.h"
#include<time.h>  //time函数所要用到的头文件
#include<stdlib.h>  //srand函数所要用到的有文件
void cshboard(char board[row][col] ,int x,int y) 
{
	int i = 0;
	int j = 0;
	for(i = 0;i<x;i++)
	{
		for(j = 0 ; j < y ; j++)
		{
			board[i][j] = ' ';
		}
	}
}
void dyboard(char board[row][col] ,int x,int y)
{
	int i = 0;
	int j = 0;
	for(i = 0;i < x;i++)
	{
		for(j = 0 ; j<y;j++)
		{
			printf(" %c " , board[i][j]);
			if(j<y-1)
			{
				printf("|");
			}
		}
		printf("\\n");
		for(j = 0;j <y;j++)
		{
			printf("---");
			if(j<y-1)
			{
				printf("|");
			}
		}
		printf("\\n");
	}
}
void playermove(char board[row][col],int x,int y)
{
	int ROW = 0;
	int COL = 0;
	while(1)
	{
		printf("玩家走\\n请输入坐标。\\n");
		scanf("%d %d" , &ROW , &COL);
		if(ROW>=1 && ROW<=x && COL>= 1 && COL<= y)
		{
			if(board[ROW-1][COL-1] == ' ')
			{
				board[ROW-1][COL-1] = '*';
				break;
			}
			else
			{
				printf("该坐标被占用\\n");
			}
		}
		else
		{
			printf("输入错误坐标。\\n");
		}
	}
}
void computermove(char board[row][col],int x,int y)
{
	int ROW = 0;
	int COL = 0;
	printf("电脑走\\n");
	while(1)
	{
		ROW = rand()%row;
		COL = rand()%col;
		if(board[ROW][COL] == ' ')
		{
			board[ROW][COL] = '#';
			break;
		}
	}
}
char pdsy(char board[row][col],int x ,int y)
{
	int i = 0;
	int j = 0;
	for(i = 0;i<x;i++)
	{
	

以上是关于三子棋代码教学的主要内容,如果未能解决你的问题,请参考以下文章

三子棋代码教学

三子棋代码教学

**入门级C语言小游戏——“三子棋” 万字保姆级教学**

数组游戏——三子棋

三子棋(会堵棋)

三子棋游戏设计及代码实现