前两天新学了数组以及它的简单应用——三子棋,这里,便将它用博客的形式写出来,复习巩固的同时也希望能够帮到你们。

文章目录

  • 一、项目要求
  • 二、项目功能的实现
    • 1.棋盘的初始化及打印
    • 2.玩家下棋
    • 3.电脑下棋
    • 4.判断游戏状态
  • 三、项目演示
    • 1.棋盘的打印
    • 2.玩家下棋
    • 3.电脑下棋
    • 4.输/赢判定
  • 四、代码展示
    • 1.game.h
    • 2.game.c
    • 3.test.c
  • 五、总结

一、项目要求

应用二维数组完成三子棋,实现其各种功能。

二、项目功能的实现

1.棋盘的初始化及打印

要开始游戏,首先我们需要打印出棋盘:

由于刚开始游戏时,玩家与电脑都没有下棋,因此,我们需要将棋盘的数据行初始化为空格。

void init_board(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 display_board(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");}}
}

2.玩家下棋

开始游戏后,先由玩家下棋。

玩家输入要下的坐标(x,y),先判断坐标的合法性(是否在棋盘的范围内),合法后,再判断该坐标是否已被占用,若没有,则落子 ‘*’。

值得注意的是,由于玩家的思维,棋盘的行、列都是从1开始,因此,我们判断合法性时,x范围应在1~ROW(最大行),y范围应在1 ~ COL(最大列),而判断坐标是否被占用时,应判断x-1,y-1。

void player_game(char board[ROW][COL], int row, int col)
{int x = 0;int y = 0;printf("请玩家下棋!\n");printf("请输入要下的坐标:");//判断输入坐标是否正确while (1){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("该坐标已被占用,请重新输入:");}}else{printf("该坐标不符合规则,请重新输入:");}}
}

3.电脑下棋

玩家下棋后,再由电脑产生随机数x,y进行下棋操作。

利用rand()函数产生随机数,要保证产生的x,y合法,只需要将产生的随机数分别取row,col的余数即可,这样,得到的x,y范围始终在0~row-1,0 ~ col-1。得到x,y的值后,再判断该坐标是否被占用,若没有,则落子 ‘#’。
在这里,由于是电脑下棋,因此,若产生的坐标已被占用,不必显示在屏幕上,直接再重新产生随机数即可。

void computer_game(char board[ROW][COL], int row, int col)
{int x = 0;int y = 0;printf("电脑下棋!\n");while (1){x = rand() % row;y = rand() % col;if (board[x][y] == ' '){board[x][y] = '#';break;}}
}

4.判断游戏状态

在这个程序中,最复杂的部分应该就是判断输赢了。我们可以将游戏状态分为4种:

’ * '——玩家赢;
’ # '——电脑赢
’ Q '——平局
’ C '——游戏继续

若有赢家,则赢的情况有三种:行、列、对角线。通过判断这三种情况并返回符合其中一种情况的任意数据,我们便可以得出赢家。

若平局,即棋盘已满,但仍无赢家,则每一次下棋后我们可以先判断是否有赢家,若没有,再判断棋盘是否已满,若棋盘已满,则为平局,返回’ Q '。

若无赢家,棋盘也未满,则返回’ C ',开始下一轮下棋。

//判断棋盘是否已满
int full_board(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 is_win(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] == board[i][(j + 1)%3] && board[i][(j + 1) % 3] == board[i][(j + 2) % 3] && board[i][j] != ' ')return board[i][0];}}//列for (j = 0; j < col; j++){for (i = 0; i < row; i++){if (board[i][j] == board[(i + 1)%3][j] && board[(i + 1) % 3][j] == board[(i + 2) % 3][j] && board[i][j] != ' ')return board[i][j];}}//主对角线for (i = 0; i < row; i++){if (board[i][i] == board[(i + 1) % 3][(i + 1) % 3] && board[(i + 1) % 3][(i + 1) % 3] == board[(i + 2) % 3][(i + 2) % 3] && board[i][i] != ' ')return board[i][i];}//副对角线for (i = 0; i < row - 2; i++){for (j = col - 1; j >= 0; j--){if (board[i][j] == board[(i + 1)%3][j - 1] && board[(i + 1)%3][j - 1] == board[(i + 2)%3][j - 2] && board[i][j] != ' ')return board[i][j];}}if (1 == full_board(board, row, col)){return 'Q';}return 'C';
}

三、项目演示

1.棋盘的打印

2.玩家下棋

3.电脑下棋

4.输/赢判定

四、代码展示

1.game.h

#pragma once#include <stdio.h>#define ROW 3
#define COL 3//初始化棋盘
void init_board(char board[ROW][COL], int row, int col);//打印棋盘
void display_board(char board[ROW][COL], int row, int col);//玩家下棋
void player_game(char board[ROW][COL], int row, int col);//电脑下棋
void computer_game(char board[ROW][COL], int row, int col);//判断游戏状态
char is_win(char board[ROW][COL], int row, int col);

2.game.c

#define _CRT_SECURE_NO_WARNINGS 1#include "game.h"void init_board(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 display_board(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 player_game(char board[ROW][COL], int row, int col)
{int x = 0;int y = 0;printf("请玩家下棋!\n");printf("请输入要下的坐标:");//判断输入坐标是否正确while (1){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("该坐标已被占用,请重新输入:");}}else{printf("该坐标不符合规则,请重新输入:");}}
}void computer_game(char board[ROW][COL], int row, int col)
{int x = 0;int y = 0;printf("电脑下棋!\n");while (1){x = rand() % row;y = rand() % col;if (board[x][y] == ' '){board[x][y] = '#';break;}}
}int full_board(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 is_win(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] == board[i][(j + 1)%3] && board[i][(j + 1) % 3] == board[i][(j + 2) % 3] && board[i][j] != ' ')return board[i][0];}}//列for (j = 0; j < col; j++){for (i = 0; i < row; i++){if (board[i][j] == board[(i + 1)%3][j] && board[(i + 1) % 3][j] == board[(i + 2) % 3][j] && board[i][j] != ' ')return board[i][j];}}//主对角线for (i = 0; i < row; i++){if (board[i][i] == board[(i + 1) % 3][(i + 1) % 3] && board[(i + 1) % 3][(i + 1) % 3] == board[(i + 2) % 3][(i + 2) % 3] && board[i][i] != ' ')return board[i][i];}//副对角线for (i = 0; i < row - 2; i++){for (j = col - 1; j >= 0; j--){if (board[i][j] == board[(i + 1)%3][j - 1] && board[(i + 1)%3][j - 1] == board[(i + 2)%3][j - 2] && board[i][j] != ' ')return board[i][j];}}if (1 == full_board(board, row, col)){return 'Q';}return 'C';
}

3.test.c

#define _CRT_SECURE_NO_WARNINGS 1#include "game.h"void menu()
{printf("********************************\n");printf("*******     1.PLAY     *********\n");printf("*******     0.EXIT     *********\n");printf("********************************\n");
}//玩家赢——‘*’
//电脑赢——‘#’
//平局  ——‘Q’
//游戏继续——‘C’void game()
{char ret = 0;char board[ROW][COL] = { 0 };init_board(board, ROW, COL);display_board(board, ROW, COL);while (1){player_game(board, ROW, COL);display_board(board, ROW, COL);ret = is_win(board, ROW, COL);if (ret != 'C')break;computer_game(board, ROW, COL);display_board(board, ROW, COL);ret = is_win(board, ROW, COL);if (ret != 'C')break;}if (ret == '*')printf("玩家胜利!\n");else if (ret == '#')printf("电脑胜利!\n");else if (ret == 'Q')printf("平局!\n");
}int main()
{srand((unsigned int)time(NULL));int input = 0;do{menu();printf("请输入你的选择:>");scanf("%d", &input);switch (input){case 1:printf("开始游戏!\n");game();break;case 0:printf("退出游戏!\n");break;default:printf("输入错误,请重新输入!\n");break;}} while (input);return 0;
}

五、总结

本次项目的代码不算困难,重要的是逻辑顺序,尤其是判定输赢那一部分。只要搞清楚了逻辑,代码写下来总体还是比较顺畅。
大家看到如果有什么不懂的地方,都可以评论或者私信问我。如果有哪些地方写得不对,也希望大家能够不吝赐教!

【三子棋】C语言实现简易三子棋相关推荐

  1. C语言实现简易三子棋,支持双人对战,电脑可拦截

    在学习二维数组后我们加以应用能写出三子棋这样一个小游戏.具体实现并不复杂. 基本思路: 游戏首先打印菜单,由我们选择单人游戏,双人游戏或退出游戏. 三子棋需要一个棋盘,我们可以通过循环打印来构造一个简 ...

  2. 用c语言实现简易三子棋

    本篇适用于C语言初学者. 目录 完整代码: 分步介绍: 声明: 代码主体部分: 模块功能实现: 完整代码: #include<stdio.h> #include <stdlib.h& ...

  3. 动物棋c语言程序,斗兽棋游戏手机版|斗兽棋游戏下载 v0.2C 安卓版_最火软件站...

    斗兽棋android手机版,动物对战棋,回味童年的棋牌休闲游戏,登陆android手机,整个游戏画面是分为两块区域,中间有河流分割两块区域,有桥梁可以让彼此的动物过河,要取得胜利,必须占领那一边动物的 ...

  4. C语言,制作三子棋游戏

    三子棋游戏是一个很好地数组应用实例,在这篇博客中我将分享我在初学C语言时编写三子棋游戏的思路和过程. 1.模块设置 设置一个测试模块test.c和一个函数模块game.c,测试模块放置主函数,函数模块 ...

  5. C语言小游戏——三子棋(井字棋)

    文章目录 前言 一.前期准备 二.游戏整体结构及思路 1.程序主体结构: 2.代码解读 3.完整源代码 总结 前言 相信大家小时候都玩过井字棋小游戏,拿石子在地上画或是用笔在纸上画······今天我们 ...

  6. 三子棋 C语言【详解】

    目录 一:游戏的介绍 二:1>游戏文件的创立 2>游戏代码各部分的实现讲解 3>游戏的运行 三:完整代码的展示 最终代码 一:游戏的介绍 二:1>游戏文件的创立 2>游戏 ...

  7. 【牛客刷题】上手用C语言写一个三子棋小游戏超详解哦(电脑优化)

    作者:[南航科院小张 南航科院小张的博客 专栏:从c语言的入门到进阶 学习知识不只是要懂,还要会用:想要找到好的工作,这里给大家介绍一件可以斩获诸多大厂offer的利器–牛客网 点击免费注册和我一起开 ...

  8. c语言井字棋程序框图,C语言实现井字棋(三子棋)

    本文实例为大家分享了C语言实现井字棋的具体代码,供大家参考,具体内容如下 一.实现思路 1.初始化数组 三子棋是九宫格的格式,所以用二维数组接收数据.用'O"代表电脑下的子,'X" ...

  9. C语言三子棋,五子棋,n子棋的代码实现

    C语言三子棋,五子棋,n子棋的代码实现 这里以五子棋为例,来说明开发过程 开发思路 菜单打印 棋盘的打印 棋子的打印 电脑下棋(随机数) 判断输赢 代码整合 注意事项 这里以五子棋为例,来说明开发过程 ...

最新文章

  1. 【Treap】bzoj1588-HNOI2002营业额统计
  2. python蜡烛图预测_python tushare股票K线蜡烛图绘制
  3. [密码学] DES(一)
  4. Python二分查找的三种思路
  5. 不同编程语言的取模运算%
  6. 如何获得带时间的ping的结果
  7. linux网络日志文件,系统日志文件 进程配置文件 进程信息文件 网络连接文件
  8. 马士兵java教程笔记_马士兵java教程笔记4
  9. SpringCloud工作笔记067---消息推送_推送视频_推送图片_在通知栏里显示图片视频_自定义点击消息后的动作
  10. Physics-based Animation 相关
  11. 浅谈CDN技术的性能与优势
  12. mysql资源限制_超出了MariaDB / MySQL资源限制
  13. 使用Pspice进行电路仿真
  14. Paper 已经过时——计算机时代科学传播方式的变革
  15. python判断闰年程序_python实现闰年
  16. 基于Esp8266的远程开机棒设计和实现
  17. 【管理经验】管理的本质-激发善意
  18. python读写文件简介(入门)
  19. kubernetes部署失败的原因
  20. UGUI文本颜色渐变

热门文章

  1. 介于上海与江苏的地铁小户型
  2. 丧尸的世界·《丧尸西游》
  3. 使用 Python 将 PDF 文件按页进行拆分
  4. Linux 系统投屏显示
  5. 小说作者推荐:张廉合集
  6. 神器VIM配置文件进阶v1.0beta
  7. 小程序中新版本的获取用户头像与昵称:bind:chooseavatar
  8. 转转代扣“支付通道费”被“放大”背后,二手交易的命门是什么?
  9. 【学习日志】2023.04.24 C++ 调整黑点、白点和中值以增加、平衡或降低对比度
  10. 面试题数组L型输出思路