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);
}