day17 C语言初阶——三子棋的实现

day17

谁能横刀立马,唯我飞牛大将军!

#三子棋的实现

说说我的想法,再给上代码。

三子棋规则:类似五子棋的模式,三子成线,即算胜出。棋盘为3行3列,这里的代码默认人先下棋

<1>先建立多文件模式,所有的固定套路写完

<2>思考 编写一个游戏,先把代码的小框架给搭出来!!!

<3>首先得有菜单吧,所以就有了我们的第一个函数void Menu()

	printf("###############################");
	printf("##### 欢迎来到三子棋游戏!#####\n");
	printf("###############################\n");
	printf("###### 1.Play     2.exit ######");
	printf("###############################");
	printf("Please select < 1 , 2 > :");

<4>联系到Menu()中有用户需要输入的select选项,所以这时我们在main.c函数中需要添加一个scanf函数

<5>用户输入一个数之后,要有一个响应的接口,这时候就可以写一个switch语句
用户输入 1,这时候游戏开始,所以又需要一个游戏的页面,这时候就要在test.c中编写一个void Game()

用户输入 2,这时候对应的是退出选项,那么处于人性的设计,我们可以写printf(“欢迎下次再玩,再见咯!\n”);再接着break退出。

用户既不输入 1,也不输入2,那么再次处于人性化的考虑,printf(“你的输入有误,请重新输入…”);接着break退出。

<6>对于一个游戏来说,我们设计的可以让用户一直玩,所以,以上的main.c中的函数语句,我们要用一个循环语句来包含他,
这时候,我们可以定义一个quit变量,int quit = 0;让循环跑起来的判断条件应该是while(!quit),那么这里修改了,case 2肯定
也要修改,否则循环会一直跑,无法终止,在case 2中添加quit = 1,这时候在while(!quit)时相当于while(0),终止循环。

<7>main.c的架子我们已经基本上搭出来了,这时候我想先测试一下我的小框架代码,那么首先在void Game()函数中编写
两个输出代码,我来简单的测试一下printf(“游戏开始!\n”); printf(“游戏结束!\n”); 好的,代码跑完没问题,我们把它注释掉。

<8>下面来搭void Game()的架子,
首先三字棋要有面板吧,所以我们定义一个面板 ,char board[ROW][COL];注意,这里要养成好习惯,那我就定义个宏 ,三字
棋3行3列,所以#define ROW 3 ,#define COL 3
定义好面板之后,我们需要初始化这个面板,于是就有了InitBoard()
下棋的时候应该是,一方下完,另一方下,所以这是个持续的过程,这里就需要用到循环,循环中我们首先是要让用户看到这个
面板,所以又需要定义一个ShowBoard()函数。默认人先走,人走完检测一下游戏是否结束,然后电脑走,再检测一下是否
游戏结束

伪代码:while(){
                        ShowBoard();
                        PlayMove();
                        JudgeResult();
                        ComputerMove();
                        JudgeResult();
                        }
             //赢了?输了?平局
             if(result){
              .......
              }

<9>架子搭完,现在可以逐个精细,

<10>现在来编写面板初始化的函数InitBoard()//将每个格都置为空格

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

}

<11>现在来编写void ShowBoard()


void ShowBoard(char board[][COL], int row, int col)
{
	printf("   | 1 | 2 | 3 |\n");
	int i = 0;
	for (; i < row; i++)
	{
		printf("----------------\n");
		printf(" %d | %c | %c | %c |\n",i+1,board[i][0],board[i][1],board[i][2]);
	}
	printf("----------------\n");
}

<12>再来编写int PlayMove() 因为编写的过程中,函数内部这里有返回值的情况,所以用int。这里有几个问题
第一,用户输入的棋子坐标不在真实的范围内,也就是输入有误的情况,我们要加以判定
x >= 1 && x <= 3 && y >= 1 && y <= 3 在这个范围内是合理的,否则是输入有误的。return 1;
第二,用户输入的坐标在范围内,但是已经被占用的情况,我们也要加以判定。return 2;
这些问题要在调用的函数,即void Game()加以说明,和给予解决办法,即:


        int type = PlayMove(board, ROW, COL);
		if (1 == type)
		{
			printf("输入有误,请重新输入....\n");
			continue;
		}
		else if (2 == type)
		{
			printf("输入的坐标已被占用,重新输入...\n");
			continue;
		}
		else
		{
			printf("用户落子完毕。\n");

<13>用户走完,要判定结果
横着连成一条线,或者竖着或者斜着

		char JudgeResult(char board[][COL], int row, int col)
//用户赢 'X'
//电脑赢 'O'
//平局 'E'
//next 'N'
{
	int i = 0 ;
	for (; i < row; i++)
	{
		if (board[i][0] != ' ' && board[i][0] == board[i][1] && board[i][1] == board[i][2])
		{
			return board[i][0];
		}
	}
	for (i=0; i < col; i++)
	{
		if (board[0][i] != ' ' && board[0][i] == board[1][i] && board[1][i] == board[2][i])
		{
			return board[0][i];
		}
	}
	if (board[0][0] != ' ' && board[0][0] == board[1][1] && board[1][1] == board[2][2])
	{
		return board[0][0];
	}
	if (board[0][2] != ' ' && board[0][2] == board[1][1] && board[1][1] == board[2][0])
	{
		return board[1][1];
	}
	for (i=0; i < row; i++)
	{
		int j = 0;
		for (; j < col; j++)
		{
			if (board[i][j] = ' ')
			{
				return 'N';
			}
		}
	}
	return 'E';

}

<14>再来编写电脑的ComputerMove(),编写电脑的函数,需要随机数种子涉及到头文件time.h,stdlib.h

void  ComputerMove(char board[][COL], int row, int col)
{
	while (1)
	{
		int i = rand() % row;
		int j = rand() % col;
		if (board[i][j] == ' ')
		{
			board[i][j] = WHITE_PIECE;
			break;
		}
	}
	printf("电脑落子完毕\n");
	Sleep(500);
}

<15>电脑走完,再进行判定结果

注:以上的函数,全部需要在test.h中进行声明

最后奉上代码:

//test.h

#ifndef _TEST_H_
#define _TEST_H_

#include<stdio.h>
#include<windows.h>
#include<time.h>
#include<stdlib.h>

#pragma warning(disable:4996)

#define ROW 3
#define COL 3
#define BLACK_PIECE 'X'
#define WHITE_PIECE 'O'

void Menu();
void Game();
void InitBoard(char board[][COL], int row, int col);//第一维度可省略
void ShowBoard(char board[][COL], int row, int col);
int  PlayMove(char board[][COL], int row, int col);
char JudgeResult(char board[][COL], int row, int col);
void  ComputerMove(char board[][COL], int row, int col);

#endif

//main.c

#include"test.h"
int main()
{
	int quit = 0;
	while (!quit){
		int select = 0;
		Menu();
	    scanf("%d", &select);
		switch (select)
		{
		case 1:
			Game();
			break;
		case 2:
			printf("欢迎下次再玩,再见咯!\n");
			quit = 1;
			break;
		default:
			printf("你的输入有误,请重新输入...");
			break;
		}
	}
	system("pause");
	return 0;
}

//test.c

#include"test.h"

void Menu()
{
	printf("###############################\n");
	printf("##### 欢迎来到三子棋游戏!#####\n");
	printf("###############################\n");
	printf("###### 1.Play     2.exit ######\n");
	printf("###############################\n");
	printf("Please select < 1 , 2 > : ");
}

void Game()
{
	char board[ROW][COL];
	InitBoard(board, ROW, COL);
	char result = 'N';
	srand((unsigned long)time(NULL));
	while (1)
	{
		ShowBoard(board, ROW, COL);
		int type = PlayMove(board, ROW, COL);

		if (1 == type)
		{
			printf("输入有误,请重新输入....\n");
			continue;
		}
		else if (2 == type)
		{
			printf("输入的坐标已被占用,重新输入...\n");
			continue;
		}
		else
		{
			printf("用户落子完毕。\n");

		}

		result = JudgeResult(board, ROW, COL);
		if (result != 'N')
		{
			break;
		}

		ComputerMove(board, ROW, COL);
		result = JudgeResult(board, ROW, COL);
		if (result != 'N')
		{
			break;
		}

	}
	ShowBoard(board, ROW, COL);
	switch (result)
	{

	case BLACK_PIECE:
		printf("你赢了!\n");
		break;
	case WHITE_PIECE:
		printf("电脑赢了!");
		break;
	case 'E':
		printf("平手!\n");
		break;
	default:
		printf("有bug!\n");
		break;
	}


}

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

}

void ShowBoard(char board[][COL], int row, int col)
{
	printf("   | 1 | 2 | 3 |\n");
	int i = 0;
	for (; i < row; i++)
	{
		printf("----------------\n");
		printf(" %d | %c | %c | %c |\n", i + 1, board[i][0], board[i][1], board[i][2]);
	}
	printf("----------------\n");
}

int PlayMove(char board[][COL], int row, int col)
{
	int x = 0;
	int y = 0;
	printf("请输入你的坐标<x,y>: ");
	scanf("%d%d", &x, &y);
	if (x >= 1 && x <= 3 && y >= 1 && y <= 3)
	{
		if (board[x - 1][y - 1] != ' ')
		{
			return 2;
		}
		else{
			board[x - 1][y - 1] = BLACK_PIECE;
			return 0;
		}
	}
	else{
		return 1;//用户输入坐标有误。
	}

}

char JudgeResult(char board[][COL], int row, int col)
//用户赢 'X'
//电脑赢 'O'
//平局 'E'
//next 'N'
{
	int i = 0;
	for (; i < row; i++)
	{
		if (board[i][0] != ' ' && board[i][0] == board[i][1] && board[i][1] == board[i][2])
		{
			return board[i][0];
		}
	}
	for (i = 0; i < col; i++)
	{
		if (board[0][i] != ' ' && board[0][i] == board[1][i] && board[1][i] == board[2][i])
		{
			return board[0][i];
		}
	}
	if (board[0][0] != ' ' && board[0][0] == board[1][1] && board[1][1] == board[2][2])
	{
		return board[0][0];
	}
	if (board[0][2] != ' ' && board[0][2] == board[1][1] && board[1][1] == board[2][0])
	{
		return board[1][1];
	}
	for (i = 0; i < row; i++)
	{
		int j = 0;
		for (; j < col; j++)
		{
			if (board[i][j] == ' ')
			{
				return 'N';
			}
		}
	}
	return 'E';

}

void  ComputerMove(char board[][COL], int row, int col)
{
	while (1)
	{
		int i = rand() % row;
		int j = rand() % col;
		if (board[i][j] == ' ')
		{
			board[i][j] = WHITE_PIECE;
			break;
		}
	}
	printf("电脑落子完毕\n");
	Sleep(500);
}

That’s all. thank you!

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值