我做了这个简单的游戏,以提高我的C++。
像NoFlicker和ShowCursor这样的功能是从互联网上复制出来的,但是我自己制作了AlignString,我为此感到骄傲。
函数changeP()交换播放器。在创建此函数和编辑代码之前,我使用了player1pick和player2pick;现在更清楚了。函数Result(char p)从winCheck(pChar)获取p。pChar是active player的符号,winCheck()检查其中一种方式是否有4个块,然后返回p作为结果。
main中的第一件事也是从互联网上重标控制台。Setup()在新游戏开始前就把一切都安排好了。Pick()向active player请求列。draw()绘制字段和标记行是关于着色,但它比我想象的更复杂。
#include <iostream>
#include <string>
#include <Windows.h>
#include <conio.h>
using namespace std;
bool gameOver, p1t, p2t;
char p1[25], p2[25], player[25];// , winner[25];
const unsigned short int X = 9, Y=7;
char field[7][8];//7 - lower border, 8 - 2 side borders
int temp[7] = {6,6,6,6,6,6,6};//to know on what lvl next block will be placed
int cPick, pColor;//column pick
char pChar;//player char for later change by players desire
void NoFlicker(short int x, short int y) { //No flickering fix (Internet)
COORD pos = { x, y };
HANDLE output = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleCursorPosition(output, pos);
}//End of NoFlicker
void ShowCursor(bool showFlag) { //Show the cursor while drawing (Internet)
HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_CURSOR_INFO cursorInfo;
GetConsoleCursorInfo(out, &cursorInfo);
cursorInfo.bVisible = showFlag; // set the cursor visibility
SetConsoleCursorInfo(out, &cursorInfo);
}//End of ShowCursor
void AlignString(string text, int y) { //Aligns strings to the Middle (by me)
int size;
size = 60 - (text.length() / 2);
for (int ent = 0; ent <= y; ent++) {
cout << "\n";
}
for (int gap = 0; gap < size; gap++) {
cout << " ";
}
cout << text;
}//End of AlignString
void draw() {
NoFlicker(0, 40);
cout << "\t\t\t\t\t\t\t 1234567 \n";
for (int i = 0; i < Y; i++) {
cout << "\t\t\t\t\t\t\t";
for (int j = 0; j < X; j++) {
if (i == Y-1 || j == 0 || j == X-1) {
//SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 9);
field[i][j] = 219;
//cout << field[i][j];
}else if (cPick == j) {
//SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), pColor);
field[temp[cPick - 1]][j] = pChar;
//cout << field[i][j];
} /*else {
if (field[i][j] == 1){
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 14);
cout << field[i][j];
} else if(field[i][j] == 2) {
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), 4);
cout << field[i][j];
} else {
field[i][j] = ' ';
cout << field[i][j];
}*/
cout << field[i][j];
}cout << endl;
}
/*cout << endl;
for (int i = 0; i < 7; i++) {
cout <<temp[i];
}cout << endl;*/
}
void changeP() {//changes players
if (p1t) {
pChar = 1; //current player's symbol
pColor = 14;
strcpy_s(player, p1);//googled this function
p1t = false; //player's 1 turn
p2t = true;//player's 2 turn
}
else if (p2t) {
pChar = 2;
pColor = 4;
strcpy_s(player, p2);
p1t = true;
p2t = false;
}
}
void result(char p) {
if (p == 1) {
gameOver = true;
AlignString(p1, 1);
AlignString("Won the game! It was fair match", 1);
AlignString("New game will start in less than 10 seconds!", 10);
}
else if (p == 2) {
gameOver = true;
AlignString(p2, 1);
AlignString("Won the game! It was fair match!", 1);
//strcpy_s(winner, p1);
AlignString("New game will start in less than 10 seconds!",10);
}
}
char winCheck(char p) {
for (int i = 0; i < 7; i++) {
for (int j = 0; j < 9; j++) {
if (field[i][j] == p && field[i+1][j + 1] == p && field[i+2][j + 2] == p && field[i+3][j + 3] == p) {//Diagonal Right Down Check
return p;
}
if (field[i][j] == p && field[i][j + 1] == p && field[i][j + 2] == p && field[i][j + 3] == p) {//Horizontal Check
return p;
}
if (field[i][j] == p && field[i-1][j + 1] == p && field[i-2][j + 2] == p && field[i-3][j + 3] == p) {//Diagonal Right Up Check
return p;
}
if (field[i][j] == p && field[i - 1][j] == p && field[i - 2][j] == p && field[i - 3][j] == p) {//Vertical Check
return p;
}
}
}
}
void pick() {
AlignString(player, 1);
AlignString("you can pick your column --> ",1);
cin >> cPick;
if (cPick > 7 || cPick < 1) {
AlignString("nIllegal pick. Try again!", 1);
pick();
} else {
temp[cPick - 1] -= 1;
if (temp[cPick - 1] < 0) {
AlignString("This column is full. Try another one!",1);
pick();
}
system("cls");
}
}
void setup() {
ShowCursor(false);
gameOver = false;
p1t = true;
p2t = false;
AlignString("Player 1, write your name or how you wanna be called here --> ",5);
//cout << "\n\t\t\t\";
cin.getline(p1, 25);
AlignString("Ok now, Player 2, write your name or how you wanna be called here --> ",1);
cin.getline(p2, 25);
system("cls");
draw();
}
void main() {
HWND console = GetConsoleWindow();
RECT r;
GetWindowRect(console, &r); //stores the console's current dimensions
MoveWindow(console, r.left, r.top, 900, 900, TRUE); // 800 width, 100 height
setup();
while (!gameOver) {
changeP();
pick();
draw();
result(winCheck(pChar));
}
Sleep(10000);
main();
}发布于 2019-07-04 14:27:15
main()的用法
在C++ main()中,只能由操作系统调用从不受程序本身的影响,它是从操作系统进入程序的入口点。对…的定义main()是整数,这样它就可以将程序的状态返回给任何调用它的程序。。
由于在此程序中使用main()的递归性质,可能会发生堆栈溢出,并可能在运行此程序的计算机上造成安全风险。堆栈溢出也可能会对其他不希望的侧产生影响。
正如@TobySpeight在
main()程序中调用c++程序所指出的那样,编辑会导致未定义的行为。这意味着它几乎可以做任何事情,任何事情都是不可预料的,而且很可能是一件坏事。例如,程序中的数据可能被破坏。当我开始编程时,它可能会引起内核恐慌,从而关闭计算机。在main()中有一个非常好的循环来执行游戏,运行另一个游戏--把游戏循环和睡眠语句放到一个外部循环中。
这是一个main()的例子,没有调用它自己,它编译,我不知道它是否工作:
int main() {
HWND console = GetConsoleWindow();
RECT r;
GetWindowRect(console, &r); //stores the console's current dimensions
MoveWindow(console, r.left, r.top, 900, 900, TRUE); // 800 width, 100 height
string playAgain("no");
do {
setup();
while (!gameOver) {
changeP();
pick();
draw();
result(winCheck(pChar));
}
std::cout << "Enter yes to play again";
std::getline(std::cin, playAgain);
} while (playAgain.compare("yes") == 0);
}使用命名空间std
使用此语句可能会导致函数名和变量之间的冲突,最好使用std::cin、std::cout和std::string,而不是在代码中使用该语句。将此语句保存在头文件中可能会导致更多的混乱。当您编写更复杂的面向对象的程序时,您可能会发现自己为对象定义了cin和cout,以便它们可以被输入或输出。
全局变量
全局变量的使用使得编写和调试代码更加困难。程序中的任何地方都可以修改全局变量,而对变量的更改可能很难跟踪。
幻数
代码中的数值常量有时被称为幻数幻数,因为它不清楚它们是什么或它们的意思。
代码中使用了许多数字常量,如0、1、2、4、14、40和219。这使得代码更难阅读和理解。不清楚pColor = 4或pColor = 14在做什么,也不清楚这条声明在做什么field[i][j] = 219;
您可以使用const int PLAYER_ONE = 1;或const int FIELD_HEIGHT = 7; const int FIELD_WIDTH = 8;来定义符号常量,而不是数字。这将使代码更容易阅读,如果您需要更改字段的大小,只需要在一个位置而不是多个位置进行编辑。它还将使您更容易理解任何通过field矩阵移动的for循环。
字符串与C样式字符串
代码已经包含了C++ string类,如果p1、p2和player被定义为字符串而不是C风格的字符数组,可能会更好。内置的std::cin和std::cout已经知道如何处理string类。
使用结构或类
可能有一个表示玩家的结构或类。它可以有字段int id;、string name;和int color;。这将减少每个玩家的变量数。
std::cin >> p1.name;
std::cin >> p2.name;或者,结构或类可以包含获取用户名的函数。
https://codereview.stackexchange.com/questions/223493
复制相似问题