C语言实现三子棋

  • 游戏介绍
  • 游戏编程思路
  • 游戏代码详解
    • 主函数
    • 游戏菜单函数
    • 游戏逻辑函数
      • 初始化棋盘
      • 打印棋盘
      • 玩家下棋
      • 电脑下棋
      • 判断输赢
  • 完整代码
    • test.c
    • game_chess.c
    • game_chess.h
  • 总结

游戏介绍


三子棋,又叫九宫棋、井字棋等。是一种在3*3格子上进行的连珠游戏,和五子棋类似,由于棋盘一般不画边框,格线排成井字故得名。游戏需要的工具仅为纸和笔,然后由分别代表O和X的两个游戏者轮流在格子里留下标记(一般来说先手者为X),任意三个标记形成一条直线,则为获胜。但是,有很多时候会出现和棋的情况。

游戏编程思路


为了代码的可读性更强,将代码拆分成不同的模块。

游戏代码详解

  • 主函数


游戏玩完一把不过瘾,可以继续玩。选择do…while循环结构,无论是否玩游戏,都会进入游戏菜单。

int main()
{int input = 0;srand((unsigned int)time(NULL));do{menu();printf("请输入:>");scanf("%d", &input);switch (input){case 2:printf("1.玩家落子为'x',电脑落子为'o'。\n2.任意三个标记形成一条直线(横线,竖线,对角线),则为获胜。\n\
3.棋盘满了,仍未出现三个标记形成一条直线的情况,则为平局。\n");break;case 1:game();break;case 0:printf("退出游戏!\n");break;default:printf("输入错误,请重新输入!\n");break;}}while (input);return 0;}
  • 游戏菜单函数


打印菜单,调用menu函数。游戏菜单代码如下:

void menu()
{printf("*************三子棋游戏*************\n");printf("*********    2.游戏规则    *********\n");printf("*********    1.开始游戏    *********\n");printf("*********    0.退出游戏    *********\n");printf("***********************************\n");}

运行结果如下:

根据菜单上的数字,选择进入相应的程序去执行。
选择2,显示游戏规则。

选择1,开始游戏。

选择0,退出游戏。

选择其他数字,提示输入错误。

  • 游戏逻辑函数


为了实现三子棋游戏,封装成函数game,game函数中搭建了实现游戏的相关逻辑。

void game()
{//存储数据char board[ROW][COL];char ret = 0;//初始化棋盘InitBoard(board, ROW, COL);//打印棋盘DisplayBoard(board, ROW, COL);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 == 'x'){printf("恭喜你,玩家赢了!\n");}if (ret == 'o'){printf("很遗憾,电脑赢了!\n");}if (ret == 'Q'){printf("打成平局!\n");}DisplayBoard(board, ROW, COL);
}

玩家或者电脑在落子后能够记录下来,如果存放数据,用一个3x3的二维数组。没有落子,显示空格。玩家落子,显示x。电脑落子,显示o。存放的都是字符,选择创建一个char类型的数组。

直接创建一个3x3的二维数组,局限性太大。如果有天我们想玩5x5或者10x10的多子棋,我们需要把程序中所有3x3数组的地方都修改了,太麻烦了。我们在game.h中对数组的大小进行符号定义,如果要修改只需要在头文件中进行修改即可。此时我们定义的是3x3的棋盘。

//符号的定义,N*N的棋盘
#define ROW 3
#define COL 3

下面具体介绍各个函数的功能。

  • 初始化棋盘


初始化棋盘,调用InitBoard函数。初始化为空格,也就是数组的每个元素都是空格,遍历数组,每个元素赋值为空格。

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] = ' ';}}
}
  • 打印棋盘


初始化棋盘后,我们想把棋盘打印出来看看。打印棋盘,调用DisplayBoard函数。打印棋盘的本质就是在打印数组的内容,把数组每个元素打印出来。

void DisplayBoard(char board[ROW][COL], int row, int col)
{int i = 0;printf(" --- --- ---\n");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");}}printf(" --- --- ---\n");
}

运行结果如下:

如果没有初始化棋盘,棋盘里放的都是随机值,也就是数组没有初始化,里面的元素都是随机值,打印出来的是下面的结果:

由此可见初始化棋盘很有必要。

如果我们想要打印出5x5的棋盘,打印出来是这个样子。

这好像跟我们需要的不太一样,原因是我们上面写的打印棋盘的函数DisplayBoard不够通用,只适用于3行3列的情况,可以修改一下代码。

//打印棋盘,将棋盘打印成N*N方格
void DisplayBoard(char board[ROW][COL], int row, int col)
{int i = 0;for (i = 0; i < col; i++){printf(" ---");}printf("\n");for (i = 0; i < row; i++){int j = 0;for (j = 0; j < col; j++){printf("|");printf(" %c ", board[i][j]);}printf("|");printf("\n");if (i < row - 1){int j = 0;for (j = 0; j < col; j++){printf("|");printf("---");}printf("|");printf("\n");}}for (i = 0; i < col; i++){printf(" ---");}printf("\n");
}

打印出来的结果如下:

3x3的棋盘我们可以直接看出要落子位置的坐标,如果是10x10的呢?有些地方的坐标还需要我们去数,这时候我们可以考虑给棋盘加上坐标,这样一眼就可以看出要落子的位置坐标,对打印棋盘函数DisplayBoard再进行修改。

void DisplayBoard(char board[ROW][COL], int row, int col)
{int i = 0;printf(" ");for (i = 0; i < col; i++){printf("%4d", i + 1);}printf("\n");printf("  ");for (i = 0; i < col; i++){printf(" ---");}printf("\n");for (i = 0; i < row; i++){int j = 0;printf("%2d", i + 1);for (j = 0; j < col; j++){printf("|");printf(" %c ", board[i][j]);}printf("|");printf("\n");if (i < row - 1){int j = 0;printf("  ");for (j = 0; j < col; j++){printf("|");printf("---");}printf("|");printf("\n");}}printf("  ");for (i = 0; i < col; i++){printf(" ---");}printf("\n");
}

运行结果如下:

我们以3x3的棋盘为例解释一下上面的代码。分为三个部分。

第一部分,"---- ---- ---- " 的打印,即为红色框起来的部分,上下各打印一次,有几列就打印几次"----"。

第二部分,"| | | |" 的打印,即为黄色框起来的部分,有几行就打印几组,有几列就打印几个"| ",最后一个黄色框起来的部分 " | " 单独打印。

第三部分,"|----|----|----|" 的打印,即为蓝色框起来的部分,打印的组数比行数少1,有几列就打印几个"|----",最后一个蓝色框起来的部分”|“单独打印。

  • 玩家下棋


玩家下棋,调用PlayerMove函数。玩家要先输入落子的坐标,然后对坐标的合法性进行判断,玩家不一定是程序员,他们认为第一行第一列的坐标为(1,1),实际在数组中该点的坐标为(0,0)。若坐标是非法的,提示重新输入。最后,判断坐标是否被占用,如果坐标的位置是空格,说明没被占用,可以落子在此处,落子成功后跳出循环,如果坐标被占用,输出提示信息。玩家下完棋后再打印一下棋盘。

//玩家下棋,落子为x
//玩家要先输入坐标,然后判断坐标的合法性,最后再判断坐标是否被占用
void PlayerMove(char board[ROW][COL], int row, int col)
{int x = 0;int y = 0;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] = 'x';break;}          else{printf("坐标已被占用,请重新输入!\n");}   }else{printf("输入非法坐标,请重新输入!\n");}}
}

运行结果如下:

这时再输入(1,1),会显示如下结果:

此时是3x3的棋盘,如果输入(4,4),会显示如下结果:

  • 电脑下棋


电脑下棋,调用ComputerMove函数。电脑要随机生成落子的坐标,用到rand函数。我们可以看到rand函数的功能是生成伪随机数,返回值是int类型,需要包含的头文件是<stdlib.h>,rand函数返回一个介于0到32767之间的伪随机整数。在调用rand之前,要使用srand函数为伪随机数生成器播种。


srand函数用来设置随机起点,参数是随机数生成种子,为了使生成的随机数每次都不一样且更随机一些,选择用时间戳作为随机数生成种子,时间是一直在变化的,time函数的参数可以是NULL。

电脑落子之前也要检查随机产生的坐标位置是否被占用,如果没被占用,电脑落子,跳出循环。如果被占用,重新再生成随机坐标。电脑落子后,也要将棋盘打印出来。

//电脑下棋,落子为o
//电脑随机产生一个坐标,判断该坐标是否被占用
void ComputerMove(char board[ROW][COL], int row, int col)
{printf("电脑走:>\n");while (1){int x = rand() % row;//随机产生的坐标值在0~row-1之间int y = rand() % col;if (board[x][y] == ' '){board[x][y] = 'o';break;}}
}

rand函数返回一个介于0到32767之间的伪随机整数,3x3的棋盘,我们需要产生的随机数为0,1,2,所以我们用产生的随机数模3。rand() % row会产生一个0~row-1之间的随机值。

运行结果如下:

  • 判断输赢


判断输赢,调用IsWin函数,IsWin函数可以用来判断游戏的状态。在游戏进行的过程中一共有四种状态:玩家赢了,返回x。电脑赢了,返回o。平局,返回Q。游戏继续,返回C。

//判断棋盘是否满了,满了返回1,没满返回0
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;int j = 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 = 0;ret = IsFull(board, ROW, COL);if (ret == 1){return 'Q';}return 'C';}

运行结果如下:



我们不难发现,上面这段判断输赢的代码有一定的局限性,只能判断3行3列的情况。如果棋盘是5x5或者10x10的呢?这里对判断输赢的函数进行改进,使其通用性更高。

//判断棋盘是否满了,满了返回1,没满返回0
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;int j = 0;//判断多子棋//横行for (i = 0; i < row; i++){int count1 = 0;int j = 0;for (j = 0; j < col - 1; j++){if (board[i][j] != ' ' && board[i][j] == board[i][j + 1]){count1++;}if (count1 == ROW - 1){return board[i][j];}}}//竖列for (j = 0; j < col; j++){int count2 = 0;for (i = 0; i < row - 1; i++){if (board[i][j] != ' ' && board[i][j] == board[i + 1][j]){count2++;}if (count2 == ROW - 1){return board[i][j];}}}//对角线int count3 = 0;for (i = 0; i < row-1; i++){if (board[i][i] != ' ' && board[i][i] == board[i + 1][i + 1]){count3++;}if (count3 == ROW - 1){return board[i][i];}}int count4 = 0;for (i = 0; i < row-1 ; i++){if (board[i][row-1-i] != ' ' && board[i][row-1-i] == board[i+1][row-2-i]){count4 ++;}if (count4 == ROW - 1){return board[i][row-1-i];}}int ret = 0;ret = IsFull(board, ROW, COL);if (ret == 1){return 'Q';}return 'C';}

我们把棋盘设置成5x5的,运行结果如下:

完整代码


  • test.c

#include"game_chess.h"
void menu()
{printf("*************三子棋游戏*************\n");printf("*********    2.游戏规则    *********\n");printf("*********    1.开始游戏    *********\n");printf("*********    0.退出游戏    *********\n");printf("************************************\n");}
void game()
{//存储数据char board[ROW][COL];char ret = 0;//初始化棋盘InitBoard(board, ROW, COL);//打印棋盘DisplayBoard(board, ROW, COL);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 == 'x'){printf("恭喜你,玩家赢了!\n");}if (ret == 'o'){printf("很遗憾,电脑赢了!\n");}if (ret == 'Q'){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 2:printf("1.玩家落子为'x',电脑落子为'o'。\n2.任意三个标记形成一条直线(横线,竖线,对角线),则为获胜。\n\
3.棋盘满了,仍未出现三个标记形成一条直线的情况,则为平局。\n");break;case 1:game();break;case 0:printf("退出游戏!\n");break;default:printf("输入错误,请重新输入!\n");break;}}while (input);return 0;}
  • game_chess.c

#include"game_chess.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] = ' ';}}
}//打印棋盘,将棋盘打印成N*N方格
//void DisplayBoard(char board[ROW][COL], int row, int col)
//{//  int i = 0;
//  printf(" --- --- ---\n");
//  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");
//      }
//  }
//  printf(" --- --- ---\n");
//}
void DisplayBoard(char board[ROW][COL], int row, int col)
{int i = 0;printf(" ");for (i = 0; i < col; i++){printf("%4d", i + 1);}printf("\n");printf("  ");for (i = 0; i < col; i++){printf(" ---");}printf("\n");for (i = 0; i < row; i++){int j = 0;printf("%2d", i + 1);for (j = 0; j < col; j++){printf("|");printf(" %c ", board[i][j]);}printf("|");printf("\n");if (i < row - 1){int j = 0;printf("  ");for (j = 0; j < col; j++){printf("|");printf("---");}printf("|");printf("\n");}}printf("  ");for (i = 0; i < col; i++){printf(" ---");}printf("\n");
}
//玩家下棋,落子为x
//玩家要先输入坐标,然后判断坐标的合法性,最后再判断坐标是否被占用
void PlayerMove(char board[ROW][COL], int row, int col)
{int x = 0;int y = 0;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] = 'x';break;}          else{printf("坐标已被占用,请重新输入!\n");}   }else{printf("输入非法坐标,请重新输入!\n");}}
}//电脑下棋,落子为o
//电脑随机产生一个坐标,判断该坐标是否被占用
void ComputerMove(char board[ROW][COL], int row, int col)
{printf("电脑走:>\n");while (1){int x = rand() % row;//随机产生的坐标值在0~row-1之间int y = rand() % col;if (board[x][y] == ' '){board[x][y] = 'o';break;}}
}//判断棋盘是否满了,满了返回1,没满返回0
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;int j = 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];//}//判断多子棋//横行for (i = 0; i < row; i++){int count1 = 0;int j = 0;for (j = 0; j < col - 1; j++){if (board[i][j] != ' ' && board[i][j] == board[i][j + 1]){count1++;}if (count1 == ROW - 1){return board[i][j];}}}//竖列for (j = 0; j < col; j++){int count2 = 0;for (i = 0; i < row - 1; i++){if (board[i][j] != ' ' && board[i][j] == board[i + 1][j]){count2++;}if (count2 == ROW - 1){return board[i][j];}}}int count3 = 0;for (i = 0; i < row-1; i++){if (board[i][i] != ' ' && board[i][i] == board[i + 1][i + 1]){count3++;}if (count3 == ROW - 1){return board[i][i];}}int count4 = 0;for (i = 0; i < row-1 ; i++){if (board[i][row-1-i] != ' ' && board[i][row-1-i] == board[i+1][row-2-i]){count4 ++;}if (count4 == ROW - 1){return board[i][row-1-i];}}int ret = 0;ret = IsFull(board, ROW, COL);if (ret == 1){return 'Q';}return 'C';}
  • game_chess.h

#include<stdio.h>
#include<stdlib.h>
#include<time.h>//符号的定义,N*N的棋盘
#define ROW 3
#define COL 3//函数声明//初始化棋盘
void InitBoard(char board[ROW][COL], int row, int col);
//打印棋盘
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);//返回‘x’--玩家赢
//返回 'o' --电脑赢
//返回‘Q’--平局
//返回 'C' --游戏继续
char IsWin(char board[ROW][COL], int row, int col);

总结


本文在三子棋的基础上可以扩展到N子棋,但也只实现了最基本的功能。还有很多可以改进的地方,比如,我们可以对电脑下棋的那部分代码进行优化,使其更智能。现在的代码是电脑随机产生一个坐标,改进后,当玩家有两个子连成一条直线时,电脑可以做出判断堵住玩家的路,玩家不会这么轻易地赢棋。文中若有错误,恳请各位及时指出,感谢。

C语言实现三子棋游戏—可扩展到任意N子棋相关推荐

  1. 关于三子棋游戏的简易实现与N子棋胜利判断方法

    关于三子棋游戏的简易实现与N子棋胜利判断方法 要实现三子棋游戏,主要需要实现以下几个要求:> 需要一个棋盘,既然需要一个棋盘,棋盘是在一个平面上的,所以我们需要创建一个二维数组 棋盘的打印 玩家 ...

  2. 三子棋(n行n列n子棋)详解

    哈喽亲爱的小伙伴们大家好,真的是好久不见.前一阵子过完年之后进行了漫长的"请年茬",现在刚刚开学,从今天开始更新,基本上不出意外还是两天一篇左右.上一期给小伙伴们讲解了数组,这期来 ...

  3. html战棋游戏战棋游戏,六款不可错过的战棋游戏 将领才华始于纸上谈兵

    战棋游戏,就是在地图上按格移动人物进行作战的回合游戏模式."步步惊心"的战斗模式.掌控全场的战场指挥感.史诗般的精彩剧情,战棋游戏的这些特点,吸引了众多玩家.那些绞尽脑汁考虑每回合 ...

  4. C语言实现扫雷小游戏(扩展版)

    游戏简介 扫雷,是一款益智类小游戏. 游戏目标是找出所有没有地雷的方格,完成游戏:要是按了有地雷的方格,游戏失败:玩家可标记雷的位置.游戏以完成时间来评高低.有不同的游戏难度可选择. 实现的功能介绍 ...

  5. python井字棋游戏代码_Python实现的井字棋(Tic Tac Toe)游戏示例

    Python实现的井字棋(Tic Tac Toe)游戏示例 来源:中文源码网    浏览: 次    日期:2018年9月2日 [下载文档:  Python实现的井字棋(Tic Tac Toe)游戏示 ...

  6. 三子棋(N子棋)小游戏超详解

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 一.三子棋的游戏规则? 二.三子棋的游戏设计的大概思路? 三.设计详细思路加代码 1.首先定义一个菜单menu函数 2 ...

  7. 用C语言实现简单的一字棋游戏

    问题分析设计目录 棋盘显示和标记以及棋盘的设计 搜索树叶子节点设计 搜索树设计 节点静态估值计算 完整代码 总结 棋盘显示和标记以及棋盘的设计 用int一维数组表示一字棋的棋盘位置,0~8,数组位置i ...

  8. MCTS蒙特卡洛搜索树实现井字棋游戏

    利用蒙特卡洛搜索树实现简单的井字棋游戏,重点不是井字棋,是熟悉蒙特卡洛搜索树的应用,而且我们知道,MCTS可以应用到非常复杂的博弈游戏中,比如象棋,围棋,在搜索空间非常大的时候,普通的极大极小搜索树无 ...

  9. php 井字棋,怎样用JS做出井字棋游戏

    这次给大家带来怎样用JS做出井字棋游戏,用JS做出井字棋游戏的注意事项有哪些,下面就是实战案例,一起来看一下. 最近有一门课结束了,需要做一个井字棋的游戏,我用JavaScript写了一个.首先界面应 ...

最新文章

  1. Codeforces Round #688 (Div. 2)
  2. transformer 中的注意力机制和胶囊网络中的动态路由:它们在本质上或许具有相似性
  3. 单片机c语言出租车计时程序,基于单片机出租车计价器课题设计c语言编写(样例3)...
  4. 如何区分两列中不同数据_如何区分原装数据线和山寨数据线
  5. 微软4月13日发布Silverlight 4正式版
  6. 使用搭建的GNS3连接交换机互联互通
  7. 网页视频下载方法二:手机浏览器下载
  8. 移动端图形化报表界面设计_移动端报表设计-帆软
  9. IJCAI‘22 推荐系统论文梳理
  10. 【操作系统概念-作业9】Virtual Memory
  11. 关闭win7的程序兼容性助手
  12. 如何排版 微信公众号「代码块」之 MarkEditor
  13. Wireshark网络分析实战笔记(二)显示过滤器
  14. Windows远程控制家里的电脑
  15. Ceph集群mon节点告警case---low diskspace
  16. html需要电脑什么配置,买电脑主要看什么配置和参数
  17. 锐捷交换机,路由器,无线,ESS,EG所有操作配置命令合集
  18. IDEA使用C3P0连接Mysql数据库
  19. linux 下 飞鸽传书 最新原版的简单安装过程
  20. ajax pro,关于AjaxPro的用法

热门文章

  1. 如何高效地做游戏测试?
  2. linux和unix区别
  3. ngix服务器简单使用
  4. springboot整合redis分别实现手动缓存和注解缓存
  5. 第二批计算机专业有哪些学校,第二批!初试科目大调整,又有院校发通知,参考书、大纲都改啦!...
  6. 安装yearning
  7. Unity脚本无法挂载/The script don‘t inherit a native class that can manage a script
  8. ManagEngine:helpdesk软件的类型有哪些?
  9. target table has x column(s) but the inserted data has y column(s), including z partition column(s
  10. java double类型保留小数和四舍五入