目录
-
目的
写一个三子棋游戏,就是小时候“X”,“O”在一个3*3的格子里,谁先连成一条线,谁就赢
-
思想
一步一步来,最起码得先分几个模块
第一、游戏框架
游戏,需要有一个选择界面,是玩游戏,还是退出游戏,用函数Menu()
void Menu()
{
printf("#######欢迎来到三子棋游戏#########\n");
printf("###1.play 2.exit####\n");
printf("################################\n");
printf("请输入你的选择\n");
}
1.如果选择玩游戏,则继续后面的操作
2.如果选择退出,则直接结束
3.如果都没选,选错了,就让他重新选
int quit= 0;
while (!quit){
int select = 0;
Menu();
scanf("%d", &select);
switch (select){
case 1:
Game();
break;
case 2:
quit = 1;
break;
default:
printf("enter error");
break;
}
}
第二、游戏过程
如果选择了玩游戏
选择玩游戏就要有一个游戏入口,函数名为Game()
在Game()函数里,想实现游戏的过程也需要分几个部分,分别调用以下几种函数
1.游戏面板的初始化-> InitBoard()函数
2.游戏是一个可视化的过程,在玩游戏的过程中,需要让玩家看到棋盘-> ShowBoard()函数
3.棋盘有了,玩家就可以下棋了->PlayerMove()函数(这里是玩家先走)
4.电脑也需要下棋->ComputerMove()函数
5.下棋会有输赢,所以需要一个JudgeResult()函数,来判断输赢
第三、具体步骤
#define ROW 3 //行数
#define COL 3 //列数
#define BLACK_PIECE 'X' //玩家的棋
#define WHITE_PIECE 'O' //电脑的棋
1. InitBoard()函数
void InitBoard(char board[][COL], int row, int col)
{
for (int i = 0; i < row; i++){
for (int j = 0; j < col; j++){
board[i][j]=' ';
}
}
}
board是一个3*3的二维数组,在InitBoard()函数中,遍历数组,将每个棋盘格都初始化为空格
2. ShowBoard()函数
void ShowBoard(char board[][COL], int row, int col)
{
printf(" | 0 | 1 | 2 |\n");
int i = 0;
for (; i < row; i++){
printf("----------------\n");
printf(" %d | %c | %c | %c |\n", i, board[i][0], board[i][1], board[i][2]);
}
printf("----------------\n");
}
显示面板,让玩家能看到
3. PlayerMove()函数
int PlayerMove(char board[][COL], int row, int col)
{
int x = 0;
int y = 0;
printf("please enter your pos<x,y>#");
scanf("%d %d", &x, &y);
if (x >= 0 && x <= 2 && y >= 0 && y <= 2){
if (board[x][y] != ' '){
return 2;
}
board[x][y] = BLACK_PIECE;
return 0;
}
return 1;
}
在 PlayerMove()函数中,玩家需要输入想在棋盘中下棋的位置,但是在下棋之前,需要先判断几种情况
(1).玩家输入的下棋位置是否正确
int type=PlayerMove(board, ROW, COL);
情况1:不正确,return 1;
if (1 == type){
printf("你输入的坐标有误,请重新输入\n");
continue;
}
情况2:正确,继续
(2).在下棋位置正确的条件下,判断玩家下棋的位置是否已经有棋了
情况1:有棋,return 2;
if (2 == type){
printf("你输入的坐标已经被占用,请重新输入\n");
continue;
}
情况2:没有棋,继续
(3)下棋的位置正确,下棋的位置也没有被下过棋,就可以插入玩家的棋子了
board[x][y] = BLACK_PIECE;
插入完成后,可以输出一句 【printf("Player.....Done\n");】来显示玩家已经下好棋了
4.JudgeResult()函数
整个游戏是在一个大循环里进行的,因此下完一步棋后就要判断以下棋盘的情况,调用完 PlayerMove()后,接着调用JudgeResult()函数
棋盘会存在四种情况
- 产生一条直线上三个相同的赢家->玩家BLACK_PIECE
- 产生一条直线上三个相同的赢家->电脑WHITE_PIECE
- 棋盘还没满,return 'N';
- 棋盘满了,但是没有产生赢家,即平局,return 'E';
char JudgeResult(char board[][COL], int row, int col)
{
//任意一行有三个相同的且不为空格,代表有赢家产生
for (int i=0; i < row; i++){
if (board[i][0]!=' '&&board[i][0] == board[i][1] && board[i][1] == board[i][2]){
return board[i][0];
}
}
//任意一列有三个相同的且不为空格,代表有赢家产生
for (int 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[0][2];
}
//遍历数组,如果还有空格,则代表棋还没下完
for (int i = 0; i < row; i++){
for (int j = 0; j < col; j++){
if (board[i][j] == ' '){
return 'N';
}
}
}
//全都填完了,而且也没有产生赢家,则代表打平手了
return 'E';
}
5.ComputerMove()函数
玩家下完棋后,电脑也需要下棋,引入两个头文件,#include <time.h>和#include <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("computer.....done\n");
Sleep(100);
}
在电脑下完棋后,也需要调用JudgeResult()函数,来判断棋盘的情况
6.Game()函数
总的一套流程在Game()里实现
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=PlayerMove(board, ROW, COL);
if (1 == type){
printf("你输入的坐标有误,请重新输入\n");
continue;
}
else if (2 == type){
printf("你输入的坐标已经被占用,请重新输入\n");
continue;
}
else if(0==type){
printf("Player.....Done\n");
}
result=JudgeResult(board, ROW, COL);
if (result != 'N'){//result的值不是'N'的时候就代表棋盘已经满了,而且已经判断好了是谁输谁赢或是平局
break;
}
ComputerMove(board, ROW, COL);
result=JudgeResult(board, ROW, COL);
if (result != 'N'){
break;
}
}
ShowBoard(board, ROW, COL);
switch (result){
case 'E':
printf("平局\n");
break;
case BLACK_PIECE:
printf("你赢啦\n");
break;
case WHITE_PIECE:
printf("你输啦\n");
break;
default:
break;
}
}
每一小步汇总起来,得到一个三子棋游戏
chess.h
#include <stdio.h>
#include <Windows.h>
#include <time.h>
#include <stdlib.h>
#define ROW 3
#define COL 3
#define BLACK_PIECE 'X'
#define WHITE_PIECE 'O'
#pragma warning (disable:4996)
void Game();
void InitBoard(char board[][COL],int row,int col);
void ShowBoard(char board[][ROW], int row, int col);
int PlayerMove(char board[][COL], int row, int col);
void ComputerMove(char board[][COL], int row, int col);
char JudgeResult(char board[][COL], int row, int col);
#endif
chess.cpp
#include "chess.h"
///
//初始化棋盘
void InitBoard(char board[][COL], int row, int col)
{
for (int i = 0; i < row; i++){
for (int j = 0; j < col; j++){
board[i][j]=' ';
}
}
}
/
//展示棋盘
void ShowBoard(char board[][COL], int row, int col)
{
printf(" | 0 | 1 | 2 |\n");
int i = 0;
for (; i < row; i++){
printf("----------------\n");
printf(" %d | %c | %c | %c |\n", i, board[i][0], board[i][1], board[i][2]);
}
printf("----------------\n");
}
//
//玩家下棋
int PlayerMove(char board[][COL], int row, int col)
{
int x = 0;
int y = 0;
printf("please enter your pos<x,y>#");
scanf("%d %d", &x, &y);
if (x >= 0 && x <= 2 && y >= 0 && y <= 2){
if (board[x][y] != ' '){
return 2;
}
board[x][y] = BLACK_PIECE;
return 0;
}
return 1;
}
//
//电脑下棋
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("computer.....done\n");
Sleep(100);
}
///
//判断输赢
char JudgeResult(char board[][COL], int row, int col)
{
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 (int 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 (int i = 0; i < row; i++){
for (int j = 0; j < col; j++){
if (board[i][j] == ' '){
return 'N';
}
}
}
return 'E';
}
//
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=PlayerMove(board, ROW, COL);
if (1 == type){
printf("你输入的坐标有误,请重新输入\n");
continue;
}
else if (2 == type){
printf("你输入的坐标已经被占用,请重新输入\n");
continue;
}
else if(0==type){
printf("Player.....Done\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 'E':
printf("平局\n");
break;
case BLACK_PIECE:
printf("你赢啦\n");
break;
case WHITE_PIECE:
printf("你输啦\n");
break;
default:
break;
}
}
main.cpp
#include "chess.h"
//菜单
void Menu()
{
printf("#######欢迎来到三子棋游戏#########\n");
printf("###1.play 2.exit####\n");
printf("################################\n");
printf("请输入你的选择\n");
}
//
int main()
{
int quit= 0;
while (!quit){
int select = 0;
Menu();
scanf("%d", &select);
switch (select){
case 1:
Game();
break;
case 2:
quit = 1;
break;
default:
printf("enter error");
break;
}
}
system("pause");
return 0;
}
-
结果展示