首先,在写任何代码的时候都应该掌握增量编写的方法,切勿操之过急,一步一个脚印。写完一段先看看是否符合预期。这篇文章结合了一些想法,在写的时候,怎么去想到这些点,并将他们实现出来。
test.c 测试游戏的逻辑
游戏的模块为以下两块:
game.c 函数的实现
game.h 函数的声明
首先,可以想到当我们打开游戏的那一瞬间,会出现一个游戏菜单,当上一轮游戏结束的时候,是要继续游戏还是要退出游戏,因此这里可以写个do while结构
#include <stdio.h>
int main()
{
do {
menu();//菜单
}while ();
return 0;
}
写一个menu的菜单。
void menu()
{
printf("************************************\n");
printf("************* 1. play ***********\n");
printf("************* 0. exit ***********\n");
printf("************************************\n");
}
菜单显示完毕,需要让你选择,选择完毕再对选择进行一个判断。
#include <stdio.h>
void menu()
{
printf("************************************\n");
printf("************* 1. play ***********\n");
printf("************* 0. exit ***********\n");
printf("************************************\n");
}
int main() {
int input = 0;
do {
menu();
printf("请选择:>");
scanf("%d", &input);
switch (input)
{
case 1:
break;
case 0:
printf("退出游戏\n");
break;
default:
printf("选择错误,请重新输入\n");
break;
}
} while (input);
return 0;
然后再考虑选择case1,怎么进行游戏
三子棋的是这样的3行3列,记录的话就需要一个二维数组。
game.h中定义两个常量以便于以后进行更改
#define ROW 3
#define COl 3
运行游戏的逻辑:
void game()
{
//存放数据需要一个3*3的二维数组
char board[ROW][COl]={0};
//初始化棋盘
InitBoard(board,ROW,COl);
}
初始化棋盘该怎样去写:
记住函数的实现在game.c中
void InitBoard(char board[ROW][COL],int row,int col)
{
int i = 0;
for(i = 0;i < ROW;i++)
{
int j = 0;
for(j = 0;j < COL;j++)
{
board[i][j] = ' ';
}
}
}
这里进行初始化了,就要把他打印到屏幕上:
void DisplayBoard(char board[ROW][COL],int row,int col)
{
int i ;
int j ;
for(i = 0;i <row;i++)
{
for (j = 0;j<col;j++)
{
printf("%c ", board[i][j]);
}
printf("\n");
}
}
效果是这样:
再考虑打印行和列:
void DisplayBoard(char board[ROW][COL],int row,int col)
{
int i ;
int j ;
for(i = 0;i <row;i++)
{
printf(" %c | %c | %c \n",board[i][0],board[i][1],board[i][2]);
printf("---|---|---\n");
}
}
会发现打印结果是这样的,下面多了一排,因此
void DisplayBoard(char board[ROW][COL],int row,int col)
{
int i ;
int j ;
for(i = 0;i <row;i++)
{
printf(" %c | %c | %c \n",board[i][0],board[i][1],board[i][2]);
if(i<row-1)
{
printf("---|---|---\n");
}
}
}
少打印一行
但这样写行是可以根据define改变,而列写死了,因此需要进行改进
void DisplayBoard(char board[ROW][COL],int row,int col)
{
int i ;
int j ;
for(i = 0;i <row;i++)
{
for (j=0;j<col;j++)
{
printf(" %c ",board[i][j]);
if(j<col-1)
{
printf("|");
}
}
printf("\n");
if(i<row-1)
{
for (j=0;j<col;j++)
{
printf("---");
if (j < col - 1)
{
printf("|");
}
}
}
printf("\n");
}
}
这样行和列都可以从define定义来进行更改
接下来要考虑
//玩家下棋(这里有一个细节,正常人去看都是从1开始而忽略了数组下标是从0开始的)
void PlayerMove(char board[][COL],int row,int col)
{
int x,y;
printf("玩家下棋:>\n");
while (1)
{
printf("请输入要下棋的坐标:>");
scanf("%d %d",&x,&y);
if(x>=1 && x<=row && y>=1 && y<=col)
{
if(board[x-1][y-1]==' ')
{
board[x-1][y-1]='*';
break;
} else
{
printf("坐标被占用,请重新输入\n");
}
} else
{
printf("坐标非法,请重新输入\n");
}
}
}
//打印棋盘
调用前面的函数Displayboard
//判断输赢
//电脑下棋
void ComputMove(char board[][COL],int row,int col)
{
int x=0,y=0;
printf("电脑下棋>:\n");
while (1)
{
x=rand()%row;
y=rand()%col;
if(board[x][y]==' ')
{
board[x][y]='#';
break;
}
}
}
//打印棋盘
//判断输赢
判断输赢也会有四种结果:
//玩家赢 返回‘*’
//电脑赢 返回‘#’
int i=0;
for (i=0;i<row;i++)//一行
{
if (board[i][0]==board[i][1] && board[i][1]==board[i][2] && board[i][0]!=' ')
{
return board[i][0];
}
}
for (i = 0; i < col; i++)//一列
{
if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[0][i] != ' ')
{
return board[0][i];
}
}
if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' ')//一撇
{
return board[1][1];
}
if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ' ')//一腊
{
return board[1][1];
}
//平局 返回‘Q’
char IsFull(char board[][COL],int row,int col)//形参
{
int i,j;
for (i=0;i<row;i++)
{
for (j=0;j<col;j++)
{
if (board[i][j]==' ')
{
return 0;
}
}
}
return 1;
}
//继续 返回‘C’
接下来就是全部的代码示例:
game.c
//
// Created by yiming Zhang on 11/1/23.
//
// Created by yiming Zhang on 11/1/23.
//
#include "game.h"
//函数的声明
//初始化棋盘
void InitBoard(char board[ROW][COL],int row,int col)
{
int i = 0;
for(i = 0;i < row;i++)
{
int j = 0;
for(j = 0;j < col;j++)
{
board[i][j] = ' ';
}
}
//也可以将这里替换为memset(&board[0][0],' ',ROW*COL*sizeof(board[0][0]));
}
void DisplayBoard(char board[][COL],int row,int col)
{
int i ;
int j ;
for(i = 0;i <row;i++)
{
for (j=0;j<col;j++)
{
printf(" %c ",board[i][j]);
if(j<col-1)
{
printf("|");
}
}
printf("\n");
if(i<row-1)
{
for (j=0;j<col;j++)
{
printf("---");
if (j < col - 1)
{
printf("|");
}
}
}
printf("\n");
}
}
void PlayerMove(char board[][COL],int row,int col)
{
int x,y;
printf("玩家下棋:>\n");
while (1)
{
printf("请输入要下棋的坐标:>");
scanf("%d %d",&x,&y);
if(x>=1 && x<=row && y>=1 && y<=col)
{
if(board[x-1][y-1]==' ')
{
board[x-1][y-1]='*';
break;
} else
{
printf("坐标被占用,请重新输入\n");
}
} else
{
printf("坐标非法,请重新输入\n");
}
}
}
void ComputMove(char board[][COL],int row,int col)
{
int x=0,y=0;
printf("电脑下棋>:\n");
while (1)
{
x=rand()%row;
y=rand()%col;
if(board[x][y]==' ')
{
board[x][y]='#';
break;
}
}
}
//判断平局
char IsFull(char board[][COL],int row,int col)//形参
{
int i,j;
for (i=0;i<row;i++)
{
for (j=0;j<col;j++)
{
if (board[i][j]==' ')
{
return 0;
}
}
}
return 1;
}
char IsWin(char board[][COL],int row,int col)
{
int i=0;
for (i=0;i<row;i++)//一行
{
if (board[i][0]==board[i][1] && board[i][1]==board[i][2] && board[i][0]!=' ')
{
return board[i][0];
}
}
for (i = 0; i < col; i++)//一列
{
if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[0][i] != ' ')
{
return board[0][i];
}
}
if (board[0][0] == board[1][1] && board[1][1] == board[2][2] && board[1][1] != ' ')//一撇
{
return board[1][1];
}
if (board[0][2] == board[1][1] && board[1][1] == board[2][0] && board[1][1] != ' ')//一腊
{
return board[1][1];
}
//判断平局
if(IsFull(board,row,col))//这里函数调用(call)的时候用的是实参
{
return 'Q';
}
//游戏继续
return 'C';
}
main.c
#include "game.h"
void menu()
{
printf("************************************\n");
printf("************* 1. play ***********\n");
printf("************* 0. exit ***********\n");
printf("************************************\n");
}
void game()
{
//存放数据需要一个3*3的二维数组
char board[ROW][COL]={0};
//初始化棋盘
InitBoard(board,ROW,COL);
DisplayBoard(board,ROW,COL);
char ret=0;
while (1)
{
//玩家下棋
PlayerMove(board,ROW,COL);
//打印棋盘
DisplayBoard(board,ROW,COL);
//判断输赢
ret= IsWin(board,ROW,COL);
if (ret!='C')
{
break;
}
//电脑下棋
ComputMove(board,ROW,COL);
//打印棋盘
DisplayBoard(board,ROW,COL);
//判断输赢
ret= IsWin(board,ROW,COL);
if (ret!='C')
{
break;
}
}
if ('*'==ret)
{
printf("玩家赢\n");
} else if ('#'==ret)
{
printf("电脑赢\n");
} else if ('Q'==ret)
{
printf("平局\n");
}
}
int main() {
int input = 0;
srand((unsigned int )time(NULL));
do {
menu();
printf("请选择:>");
scanf("%d", &input);
switch (input)
{
case 1:
game();
break;
case 0:
printf("退出游戏\n");
break;
default:
printf("选择错误,请重新输入\n");
break;
}
} while (input);
return 0;
}
game.h
//
// Created by yiming Zhang on 11/1/23.
//
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <stdlib.h>
#ifndef INC_2_GAME_H
#define INC_2_GAME_H
#define ROW 3
#define COL 3
#endif //INC_2_GAME_H
void InitBoard(char board[ROW][COL],int row,int col);
void DisplayBoard(char board[ROW][COL],int row,int col);
void PlayerMove(char board[][COL],int row,int col);
void ComputMove(char board[][COL],int row,int col);
char IsWin(char board[][COL],int row,int col);
Game:扫雷
基本界面如下: