基于C語言實(shí)現(xiàn)三子棋小游戲
在寫三子棋之前,我們要先了解三子棋的一個(gè)大概的圖形,以便于我們整理思路。
首先我們要分模塊寫代碼,不要全部寫在主函數(shù)里面,模塊化的代碼便于理解,而且給人一種賞心悅目的感覺,如:
game.h
game.c
test.c
game.h---頭文件的包含,定義宏變量以及函數(shù)聲明
#pragma once //頭文件的包含 #include<stdio.h> #include<stdlib.h> #include<time.h> //函數(shù)的聲明 #define ROW 3 #define COL 3 //函數(shù)的聲明 //初始化棋盤的函數(shù) void InitBoard(char board[ROW][COL], int row, int col); //打印棋盤的函數(shù) void DisplayBoard(char board[ROW][COL], int row, int col); //玩家下棋 void PlayerMove(char board[ROW][COL], int row, int col); //電腦下棋 void ComputerMove(char board[ROW][COL], int row, int col); //判斷游戲是否有輸贏 char IsWin(char board[ROW][COL], int row, int col);
這樣的好處是:例如后期想在這個(gè)代碼的基礎(chǔ)上改成十乘十的棋盤的時(shí)候,我們只需將頭文件中的函數(shù)聲明處的宏定義改為十即可 ,而不需要在每次傳參以及定義處更改,這樣便于節(jié)省很多不必要的步驟,大大提高寫程序的效率。
test.c---游戲思路
#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
void menu() {
printf("***********************\n");
printf("******* 1.play ********\n");
printf("******* 2.exit ********\n");
printf("***********************\n");
}
void game()
{
//存儲數(shù)據(jù) - 二維數(shù)組
char board[ROW][COL];
//初始化棋盤 - 初始化空格
InitBoard(board, ROW, COL);
//打印棋盤 - 本質(zhì)是打印數(shù)組的內(nèi)容
DisplayBoard(board, ROW, COL);
char ret = 0;//接收游戲狀態(tài)
while (1)
{
//玩家下棋
PlayerMove(board, ROW, COL);
DisplayBoard(board, ROW, COL);
//判斷玩家是否贏的游戲
ret = IsWin(board, ROW, COL);
if (ret != 'c')
break;
//電腦下棋
ComputerMove(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
{
printf("平局\n");
}
DisplayBoard(board, ROW, COL);
}
int main()
{
int input = 0;
srand((unsigned int)time(NULL));
do {
menu();
printf("請選擇:>");
scanf("%d", &input);
switch (input)
{
case 1:
game();
break;
case 2:
printf("退出游戲!\n");
break;
default:
printf("選擇錯(cuò)誤!\n");
break;
}
} while (1);
return 0;
}
建議:我們在寫代碼的時(shí)候,每個(gè)步驟前可以適當(dāng)?shù)募右恍┳⑨?,這樣即使代碼很長,當(dāng)我們運(yùn)行有錯(cuò)誤的時(shí)候,或者后期回顧的時(shí)候,可以很容易的找出錯(cuò)誤點(diǎn),而且能夠很清晰的看出哪一塊代碼是在實(shí)現(xiàn)什么功能,不僅方便自己復(fù)習(xí),當(dāng)朋友借鑒的時(shí)候也可以讓朋友通俗易懂,能夠快速產(chǎn)生共鳴。
game.c---游戲的實(shí)現(xiàn)
#define _CRT_SECURE_NO_WARNINGS 1
#include"game.h"
// 初始化棋盤
void InitBoard(char board[ROW][COL], int row, int col)
{
int i = 0;
int j = 0;
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
board[i][j] = ' ';
}
}
}
// 打印棋盤
void DisplayBoard(char board[ROW][COL], int row, int col)
{
int i = 0;
int j = 0;
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[ROW][COL], int row, int col)
{
int x = 0;
int y = 0;
printf("玩家走:>\n");
while (1)
{
printf("請輸入下棋的坐標(biāo):>\n");
scanf("%d %d", &x, &y);
//判斷坐標(biāo)的合法
if (x >= 1 && x <= row && y >= 1 && y <= col)
{
//下棋
//坐標(biāo)是否被占用
if (board[x - 1][y - 1] == ' ')
{
board[x - 1][y - 1] = '*';
break;
}
else
{
printf("坐標(biāo)被占用,請重新輸入\n");
}
}
else
{
printf("坐標(biāo)非法,請重新輸入\n");
}
}
}
// 電腦走
void ComputerMove(char board[ROW][COL], int row, int col)
{
printf("電腦走:>\n");
while (1)
{
int x = rand() % row;//0-2
int y = rand() % col;//0-2
//判斷坐標(biāo)被占用
if (board[x][y] == ' ')
{
board[x][y] = '#';
break;
}
}
}
// 判滿
int IsFull(char board[ROW][COL], int row, int col)
{
int i = 0;
int j = 0;
for (i = 0; i < row; i++)
{
for (j = 0; j < col; j++)
{
if (board[i][j] == ' ')
return 0; //棋盤沒滿,還有空格
}
}
return 1; //棋盤滿了
}
// 判斷輸贏
char IsWin(char board[ROW][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][1] != ' ')
{
return board[i][1];
}
}
//判斷三列
for (i = 0; i < col; i++)
{
if (board[0][i] == board[1][i] && board[1][i] == board[2][i] && board[1][i] != ' ')
{
return board[1][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];
}
//判斷平局
int ret = IsFull(board, row, col);
if (ret == 1)
{
return 'Q';
}
//繼續(xù)
else
return 'c';
}
思考提升
從代碼中可以看出初始化棋盤沒有寫死,而判斷輸贏的時(shí)候,代碼寫死了,這里留給大家思考。
例子:提供三行改成多行的代碼

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
虛函數(shù)與純虛函數(shù)(C++與Java虛函數(shù)的區(qū)別)的深入分析
本篇文章是對虛函數(shù)與純虛函數(shù)進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-06-06
MongoDB?C?驅(qū)動(dòng)程序安裝(libmongoc)?和?BSON?庫(libbson)方法
這篇文章主要介紹了安裝?MongoDB?C?驅(qū)動(dòng)程序?(libmongoc)?和?BSON?庫?(libbson),本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-09-09

