目錄
前言
一、設計思路
二、主要步驟
1.列印和初始化棋盤
2.玩家落子和電腦落子
3.判定勝負
三、整體實作
四、心得體會
前言
井字棋是一種在3*3格子上進行的連珠游戲,和五子棋類似,由于棋盤一般不畫邊框,格線排成井字故得名,游戲需要的工具僅為紙和筆,然后由分別代表O和X的兩個游戲者輪流在格子里留下標記(一般來說先手者為X),任意三個標記形成一條直線,則為獲勝,
該小游戲會用到C語言中基礎的陣列、分支和回圈陳述句、函式等基礎知識,完成該游戲用于鞏固自己的C語言基礎知識,
一、設計思路
1.在命令列中列印出基于二維陣列的棋盤,并且盡量使界面更加美觀
2.設計一個初始化函式,使得棋盤可以全部初始化每個元素為空格字符
3.選擇游戲模式,分為玩家先手和電腦先手
4.在當前的模式之中,設計玩家落子、電腦落子以及判定勝負的函式
5.玩家落子時,判定當前是否可以落子,如果可以落子則將對應元素改為'X'
6.電腦落子時,判定當前是否可以落子,如果可以落子則將對應元素改為'O'
7.判定勝負,判定每行每列以及對角線是否都能滿足獲勝條件,并完成條件滿足后的輸出
二、主要步驟
1.列印和初始化棋盤
列印棋盤時可以借助'-''+'等字符使得界面更加美觀,為了使代碼的可讀性更高,3×3的棋盤其中的行數和列數的引數用宏定義 #define MAX_ROW 3 #define MAX_COL 3來實作,具體代碼如下,
void init(char board[MAX_ROW][MAX_COL]){
for(int row=0;row<MAX_ROW;row++){
for(int col=0;col<MAX_COL;col++){
board[row][col]=' ';
}
}
}
void print_board(char board[MAX_ROW][MAX_COL]){
system("cls");
for(int row=0;row<MAX_ROW;row++){
printf("+--+--+--+\n");
for(int col=0;col<MAX_COL;col++){
printf("|%c ",board[row][col]);
}
printf("|\n");
}
printf("+--+--+--+\n");
}
2.玩家落子和電腦落子
需要判定當前輸入是否可以落子如果可以落子就將對應元素進行修改,在以下幾種情況時無法落子,需要重新輸入,注意,還需要定義一個函式判斷當前的棋盤是否已經滿了,該函式在判定勝負時也需要用到,
1.棋盤已經滿
2.當前位置有子
3.輸入越界
void player_move(char board[MAX_ROW][MAX_COL]){
printf("請玩家落子!\n");
while(1){
printf("請輸入落子位置的行列號:");
int row=0;
int col=0;
scanf("%d %d",&row,&col);
if(isFull(board)){
break;
}
if(row<0||row>MAX_ROW||col<0||col>MAX_COL){
printf("您的輸入有誤!請重新輸入\n");
continue;
}
else if(board[row][col]!=' '){
printf("當前位置有子!無法落子!\n");
continue;
}
else{
board[row][col]='X';
break;
}
}
}
void computerMove(char board[MAX_ROW][MAX_COL]){
srand((unsigned int)time(0));
//printf("電腦落子\n");
while(1){
int row =rand()%MAX_ROW;
int col =rand()%MAX_COL;
if(!isFull(board)){
if(board[row][col]!=' '){
continue;
}else{
board[row][col]='O';
break;
}
}else{
break;
}
}
}
int isFull(char board[MAX_ROW][MAX_COL]){
for(int row=0;row<MAX_ROW;row++){
for(int col=0;col<MAX_COL;col++){
if(board[row][col]==' '){
return 0;
}
}
}
return 1;
}
3.判定勝負
如果當前棋盤未滿則回傳空格字符' ',如果存在每行元素或者每列元素以及對角線元素相等,則回傳對應的字符,如果棋盤已經滿了并且沒有滿足勝利條件,判定為和棋,
char checkWinner(char board[MAX_ROW][MAX_COL]){
for(int row=0;row<MAX_ROW;row++){
if(board[row][0]!=' '&&board[row][0]==board[row][1]&&board[row][0]==board[row][2]){
return board[row][0];
}
}
for(int col=0;col<MAX_ROW;col++){
if(board[0][col]!=' '&&board[0][col]==board[1][col]&&board[0][col]==board[2][col]){
return board[0][col];
}
}
if(board[1][1]!=' '&&board[0][0]==board[1][1]&&board[0][0]==board[2][2]){
return board[1][1];
}
if(board[1][1]!=' '&&board[0][2]==board[1][1]&&board[0][2]==board[2][0]){
return board[1][1];
}
if(isFull(board)){
return '=';
}
return ' ';
}
三、整體實作
我們需要使游戲處于一個回圈中,滿足勝負條件時退出回圈并且判定勝負,需要選擇游戲模式為玩家先手以及電腦先手,并且在每次落子之后都需要列印棋盤判定勝負,整體的游戲代碼如下所示,
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define MAX_ROW 3
#define MAX_COL 3
void init(char board[MAX_ROW][MAX_COL]){
for(int row=0;row<MAX_ROW;row++){
for(int col=0;col<MAX_COL;col++){
board[row][col]=' ';
}
}
}
void print_board(char board[MAX_ROW][MAX_COL]){
system("cls");
for(int row=0;row<MAX_ROW;row++){
printf("+--+--+--+\n");
for(int col=0;col<MAX_COL;col++){
printf("|%c ",board[row][col]);
}
printf("|\n");
}
printf("+--+--+--+\n");
}
void player_move(char board[MAX_ROW][MAX_COL]){
printf("請玩家落子!\n");
while(1){
printf("請輸入落子位置的行列號:");
int row=0;
int col=0;
scanf("%d %d",&row,&col);
if(isFull(board)){
break;
}
if(row<0||row>MAX_ROW||col<0||col>MAX_COL){
printf("您的輸入有誤!請重新輸入\n");
continue;
}
else if(board[row][col]!=' '){
printf("當前位置有子!無法落子!\n");
continue;
}
else{
board[row][col]='X';
break;
}
}
}
void computerMove(char board[MAX_ROW][MAX_COL]){
srand((unsigned int)time(0));
//printf("電腦落子\n");
while(1){
int row =rand()%MAX_ROW;
int col =rand()%MAX_COL;
if(!isFull(board)){
if(board[row][col]!=' '){
continue;
}else{
board[row][col]='O';
break;
}
}else{
break;
}
}
}
int isFull(char board[MAX_ROW][MAX_COL]){
for(int row=0;row<MAX_ROW;row++){
for(int col=0;col<MAX_COL;col++){
if(board[row][col]==' '){
return 0;
}
}
}
return 1;
}
//玩家獲勝回傳X,電腦獲勝回傳O,和棋回傳=,勝負未分回傳' '.
char checkWinner(char board[MAX_ROW][MAX_COL]){
for(int row=0;row<MAX_ROW;row++){
if(board[row][0]!=' '&&board[row][0]==board[row][1]&&board[row][0]==board[row][2]){
return board[row][0];
}
}
for(int col=0;col<MAX_ROW;col++){
if(board[0][col]!=' '&&board[0][col]==board[1][col]&&board[0][col]==board[2][col]){
return board[0][col];
}
}
if(board[1][1]!=' '&&board[0][0]==board[1][1]&&board[0][0]==board[2][2]){
return board[1][1];
}
if(board[1][1]!=' '&&board[0][2]==board[1][1]&&board[0][2]==board[2][0]){
return board[1][1];
}
if(isFull(board)){
return '=';
}
return ' ';
}
int main()
{
char board[MAX_ROW][MAX_COL]={0};
init(board);
char winner=' ';
printf("請選擇誰先落子(輸入0電腦先,輸入1玩家先):");
int a=0;
scanf("%d",&a);
if(a==1){
while(1){
print_board(board);
player_move(board);
print_board(board);
winner=checkWinner(board);
if(winner!=' '){
break;
}
computerMove(board);
print_board(board);
winner=checkWinner(board);
if(winner!=' '){
break;
}
}
if(winner=='X'){
printf("恭喜你!你贏了");
}
if(winner=='O'){
printf("菜菜菜菜菜菜菜菜");
}
if(winner=='='){
printf("你和人工智障五五開");
}
}else if(a==0){
while(1){
print_board(board);
computerMove(board);
print_board(board);
winner=checkWinner(board);
if(winner!=' '){
break;
}
player_move(board);
print_board(board);
winner=checkWinner(board);
if(winner!=' '){
break;
}
}
if(winner=='X'){
printf("恭喜你!你贏了");
}
if(winner=='O'){
printf("菜菜菜菜菜菜菜菜");
}
if(winner=='='){
printf("你和人工智障五五開");
}
}
return 0;
}
四、心得體會
最好永遠不要用scanf函式,在該游戲中如果不按照要求輸入的話會使游戲陷入一個死回圈,無法繼續游戲,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/317679.html
標籤:其他
上一篇:游戲大綱細化
下一篇:C語言最詳細三子棋小游戲
