1.三子棋分析
三子棋顾名思义就是五子棋的缩小版,棋手和电脑进行博弈,当某一方棋子三子连珠,该方即为获胜方,可用符号‘#’来表示玩家棋子,‘*’代表电脑棋子,便于对弈双方的区分,该自写程序电脑执行下棋步骤还不具备识别赢棋规则,后期需要改进。 三子棋游戏需要有以下几个功能: 1.游戏菜单 2.初始化棋盘 3.当前棋盘状态界面显示 3.下棋模式 4.检测三子连珠模块 5.检测平局模块
2.建立三子棋盘模型
| |
-----|-----|-----
| |
-----|-----|-----
| |
3.功能分析和设计
3.1游戏菜单
游戏菜单至少包含以下两个功能(待补充):
- 游戏名称展示;
- 游戏进入退出选择模式;
3.1.1设计流程图
游戏菜单设计流程图如下:
Created with Rapha?l 2.3.0
start
输入模式
模式输入正确与否
是否进入游戏
进入游戏
end
yes
no
yes
no
3.1.2源码
```c源码
//利用goto语句********************************
int Intput()
{
int intput;
scanf("%d", &intput);
return intput;
}
int menu()
{
int intput;
printf("************************欢迎进入三子棋*******************\n");
printf("************************请输入以下选项*******************\n");
printf("****************0:退出游戏 1:进入游戏***************\n");
printf("***********请输入->");
loop:
intput = Intput(); //模式输入
if (intput == 0)
{
printf("****************退出游戏,再见***************\n");
}
else if (intput == 1)
{
printf("****************进入游戏*********************\n");
}
else
{
printf("***********输入错误,请重新输入**************\n");
printf("***********请输入->");
goto loop;
}
return intput;
}
//或者***************************************************
int menu()
{
int intput;
printf("************************欢迎进入三子棋*******************\n");
printf("************************请输入以下选项*******************\n");
printf("****************0:退出游戏 1:进入游戏***************\n");
printf("***********请输入->");
while (1)
{
scanf("%d", &intput);
if (intput == 0)
{
printf("****************退出游戏,再见***************\n");
break;
}
else if (intput == 1)
{
printf("****************进入游戏*********************\n");
break;
}
else
{
printf("***********输入错误,请重新输入**************\n");
printf("***********请输入->");
}
}
return intput;
}
3.2游戏功能
3.2.1游戏函数功能
游戏函数需包含显示棋盘函数,下棋函数和下棋结果判断等功能.
3.2.1.1分析
3.2.1.2源码
void game()
{
//int rows, columns;
//int not_draw;//平局
//char sign;
//存放棋盘信息
char board[ROWS][COLUMNS] = { 'a','a','a','a','a','a','a','a','a' };//全部为空格
//初始化棋盘
Initi_board(board,ROWS,COLUMNS);
//打印棋盘
display_board(board, ROWS, COLUMNS);
printf("\n");
while (1)
{
//玩家走棋
playermove(board, ROWS, COLUMNS);
display_board(board, ROWS, COLUMNS);
printf("\n");
int ret = winner(board, ROWS, COLUMNS, '#');
if (ret)
{
printf("玩家获胜,结束比赛");
break;
}
else
{
if (judge_draw(board, ROWS, COLUMNS))
{
printf("双方平局,结束游戏");
break;
}
}
//电脑走棋
computermove(board, ROWS, COLUMNS);
display_board(board, ROWS, COLUMNS);
printf("\n");
ret = winner(board, ROWS, COLUMNS, '*');
if (ret)
{
printf("电脑获胜,结束比赛");
break;
}
else
{
if (judge_draw(board, ROWS, COLUMNS))
{
printf("双方平局,结束游戏");
break;
}
}
}
}
3.2.2初始化棋盘
3.2.2.1分析
根据棋盘架构得知棋盘的棋子字符构成3 * 3的数组,创建二维3 * 3数组并赋空字符初值,初始化棋盘。主函数创建二维数组后,需将二维数组传入棋盘初始化函数进行数组初始化,二维数组的行列值可由全局变量进行创建,便于以后进行多子棋设计。
3.2.2.2源码
//利用传址调用,将二维数组地址传入初始化棋盘函数,因利用函数参数1类型为数组指针,所以需利用其它参数将数组的行列值传入函数
void Initi_board(char(*board)[COLUMNS], int rows, int colunms)
{
int i,j;
for (i = 0;i < rows; i++)
{
for (j = 0; j <colunms; j++)
{
//*(*(board+i)+j) = ' ';
board[i][j] = ' ';
}
}
}
3.2.3棋盘显示函数
3.2.3.1分析
根据棋盘架构得知棋盘的棋子字符构成3 * 3的数组。 其中每一行都是由以下模型创建:
| |
-----|-----|-----
其中每一列都是由以下模型创建:
|
-----|
|
-----|
|
当在最后一行没有-----|-----|-----模型,当在最后一列时,没有‘|’模型,需进行不显示处理
3.2.3.2源码
void display_board(char(*board)[COLUMNS], int rows, int colunms)
{
int i,j;
for (i = 0; i < rows; i++)
{
for (j = 0; j < colunms; j++)
{
printf(" %c ",board[i][j]);
if (j<colunms-1)
printf("|");
}
printf("\n");
if (i<rows-1)
for (j = 0; j < colunms; j++)
{
printf("---");
if(j < colunms - 1)
printf("|");
}
printf("\n");
}
}
3.2.4下棋模块
3.2.4.1 玩家下棋模块
3.2.4.1.1 分析
将棋子放在相应的横纵坐标即可,横纵坐标对应着相应的二维数组,对二维数组成员进行赋值
3.2.4.1.2 源码
void playermove(char(*board)[COLUMNS], int rows, int colunms)
{
int x, y;
while (1)
{
printf("玩家请在合法坐标处填入#\n");
printf("请输入x,y坐标:");
scanf("%d%d", &x,&y);
//printf("请输入y坐标:");
//scanf("%d", &y);
if (x >= 1 && x <= rows && y >= 1 && y <= colunms)
{
if (board[x - 1][y - 1] == ' ')
{
board[x - 1][y - 1] = '#';
break;
}
else
{
printf("该位置已有棋子请重新输入");
}
}
else
{
printf("输入错误请重新输入");
}
}
}
3.2.4.2 电脑下棋模块
3.2.4.2.1 分析
电脑模式下用随机数模式,产生随机坐标(当前电脑下棋函数没有按照赢棋规则下棋逻辑)
3.3.4.2.2 源码
void computermove(char(*board)[COLUMNS], int rows, int colunms)
{
int x, y;
time_t* timer1 = NULL;
time_t* timer2 = NULL;
printf("请电脑执行下棋填入*\n");
while (1)
{
srand((unsigned int)time(timer1));//利用时间戳播种
Sleep(500);
srand((unsigned int)time(timer2));
x = rand() % rows + 1;//产生随机x坐标
y = rand() % colunms + 1;
if (x >= 1 && x <= rows && y >= 1 && y <= colunms)
{
if (board[x - 1][y - 1] == ' ')
{
board[x - 1][y - 1] = '*';
break;
}
}
}
}
3.2.5结果判断
3.2.5.1 分析
利用循环判断某一坐标下横向三子连珠,纵向三子连珠和,左下,右下三子连珠情况. 若未产生取胜一方,需判断当前二维数组已经填满,若填满则为平局结果.
3.2.5.2 源码
//赢家判断模式
int winner(char(*board)[COLUMNS], int rows, int colunms,char ch)
{
int x = 0, y = 0, z = 0;
signed char z1=0,z2=0;
int ret=0,cycle_num=0;
//检测行连子情况
for (x = 0; x < rows; x++)
{
for (y = 0; y + 2 < colunms;)
{
z = y;
while (1)
{
cycle_num++;
if (board[x][z] != ch)
{
y = y + cycle_num;
cycle_num = 0;
z = 0;
break;
}
else if (cycle_num == 3)
{
cycle_num = 0;
ret = 1;
return ret;
}
z++;
}
}
}
//检测列连子情况
for (y = 0; y < colunms; y++)
{
for (x = 0; x + 2 < rows;)
{
z = x;
while (1)
{
cycle_num++;
if (board[z][y] != ch)
{
x = x + cycle_num;
cycle_num = 0;
z = 0;
break;
}
else if (cycle_num == 3)
{
cycle_num = 0;
ret = 1;
return ret;
}
z++;
}
}
}
//检测左下右下方向连子情况
for (x = 0; x < rows; x++)
{
for (y = 0; y < colunms;y++)
{
for (z1 = x, z2 = y, cycle_num = 0; z1 < rows && z2 < colunms;)
{
cycle_num++;
if (board[z1][z2] != ch)
{
break;
}
else if (cycle_num == 3)
{
ret = 1;
return ret;
}
z1++;
z2++;
}
for (z1 = x, z2 = y, cycle_num = 0; z1 < rows && z2 >= 0;)
{
cycle_num++;
if (board[z1][z2] != ch)
{
break;
}
else if (cycle_num == 3)
{
ret = 1;
return ret;
}
z1++;
z2--;
}
}
}
return 0;
}
//平局判断模式
int judge_draw(char(*board)[COLUMNS], int rows, int colunms)
{
int x, y;
for (x = 0; x < rows; x++)
{
for (y = 0; y < colunms; y++)
{
if (board[x][y] == ' ')
{
return 0;
}
}
}
return 1;
}
3.3头文件声明函数
#pragma once
#define ROWS 3
#define COLUMNS 3
#include<stdio.h>
#include<time.h>
#include<stdlib.h>
#include<windows.h>
#ifndef __HEAD_H__
#define __HEAD_H__
//声明函数
void Initi_board(char(*board)[COLUMNS], int rows, int colunms);
void display_board(char(*board)[COLUMNS], int rows, int colunms);
void playermove(char(*board)[COLUMNS], int rows, int colunms);
void computermove(char(*board)[COLUMNS], int rows, int colunms);
int winner(char(*board)[COLUMNS], int rows, int colunms, char ch);
int judge_draw(char(*board)[COLUMNS], int rows, int colunms);
#endif
3.4主函数调用
int main()
{
while (1)
{
if (menu() == 1)
{
game();
break;
}
else
{
break;
}
}
return 0;
}
|