在连接 4 C++算法中检查获胜者
Checking Winner in connect 4 C++ Algorithm
我已经在这些代码段上呆了几个小时,我被困在这一段代码所需的算法上。我讨厌成为发布整个代码的人,但我觉得这是必要的,这样你才能理解它。我完全被困在如何检查获胜者上。我认为可以递归完成,但在与一些人交谈后,他们说这不是最好的方法。我完全不知道如何解决这个问题。
#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>
#include <time.h>
#include <iostream>
/**
* @brief Check if a winner exists
*
* @param pBoard The board
* @param colSize The column size
* @param rowSize The row size
*
* @return The character of the winner, 0 for no winner, and 't' for a tie
*/
char checkWinner(char** pBoard, int colSize, int rowSize, int winSize) {
// TODO
**This is where the algorithm needs to go.**
return 0;
}
/**
* @brief Place a piece onto the board
*
* @param pBoard The game board
* @param colSize The column size
* @param rowSize the row size
* @param columnSelection The column selection
* @param player The players characterS
*
* @return True if the piece was placed, else false
*/
bool placePiece(char** pBoard, int colSize, int rowSize, int columnSelection, char player)
{
// TODO
int row = rowSize-1;
while (pBoard[row][columnSelection]!= ' ' && row > 0){
row--;
}
std::cout << row << std::endl;
if (pBoard[row][columnSelection] == ' ') {
pBoard[row][columnSelection] = player;
return true;
} else{
std::cout << "The space is full." << std::endl;
return false;
}
}
/**
* @brief Print out the game board
*
* @param pBoard The game board
* @param colSize The column size
* @param rowSize The row size
*/
void printBoard(char** pBoard, int colSize, int rowSize) {
for (int i = 0; i <= rowSize; ++i){
std::cout << "|" << i;
}
std:: cout << "|" << std::endl;
for (int i = 0; i < rowSize; ++i){
std::cout << "|";
for (int j = 0; j < colSize; ++j){
std::cout << pBoard[i][j] << "|";
}
std::cout << std::endl;
}
std::cout << std::endl;
}
int main()
{
bool running = true;
printf("Welcome to connect four!n");
srand (time(NULL));
int32_t connectedPiecesToWin = 0;
int32_t rowSize = 0;
int32_t colSize = 0;
// setup game
std::cout << "How many connected pieces does it take to win?" << std::endl;
std::cin >> connectedPiecesToWin;
rowSize = connectedPiecesToWin + 2;
colSize = connectedPiecesToWin + 3;
std::cout << "You have selected " << connectedPiecesToWin << " in a row with a game board of " << colSize
<< " x " << rowSize << std::endl;
// setup board
char** pBoard = NULL; // TODO create the game board
// initialize board
pBoard = new char*[rowSize];
for (int i = 0; i < rowSize; ++i){
pBoard[i] = new char[colSize];
}
for(int i = 0; i < rowSize; ++i){
for(int j = 0; j < colSize; ++j){
pBoard[i][j]= ' ';
}
}
// play
char winner = 0;
char player = 'p';
do
{
int columnChoice = 0;
do
{
if (player == 'p')
{
printBoard(pBoard, colSize, rowSize);
std::cout << "Player's column: ";
std::cin >> columnChoice;
}
else
{
// computers turn
columnChoice = rand() % colSize;
}
} while (!placePiece(pBoard, colSize, rowSize, columnChoice, player));
winner = checkWinner(pBoard, colSize, rowSize, connectedPiecesToWin);
player = (player == 'c') ? 'p' : 'c';
} while (running && winner == 0);
printBoard(pBoard, colSize, rowSize);
if (winner == 't')
{
std::cout << "Too bad, the game was a tie!" << std::endl;
}
else if (winner == 'c')
{
std::cout << "Oh man, you lost to a computer that randomly places pieces!" << std::endl;
}
else
{
std::cout << "Congrats! You won!" << std::endl;
}
// cleanup
// TODO cleanup the board
for (int i = 0; i < rowSize; ++i){
delete[] pBoard[i];
}
delete[] pBoard;
return 0;
}
暴力方法是测试每个单元格,以查看它是否在任何有效方向上连接到连接的 PiecesToWin 片段,因此首先编写一个例程,如果 0,0 处的单元格是获胜单元格,则返回 true:
- 选择一个偏移量进行搜索,例如 -1
- ,-1 进行对角线搜索
- 对于该偏移量:
- 检查与目标单元格偏移的单元格是否为相同颜色。
- 如果是,则递增计数器并再次执行相同的测试在偏移单元的偏移量处(此处有一点递归(
- 当您撞到墙上或同色单元格的数量大于或等于 connectedPiecesToWin.
选取下一个偏移量 (-1,0(、( - 0,-1(、(1,1( 等。
- 如果您搜索所有八个方向并且没有得到胜利返回假。
然后,这个例程是在整个董事会中搜索获胜单元的关键,或者只是检查刚刚做出的举动是否创造了胜利。
还是我错过了什么?
由于这显然是家庭作业,我将在不提供实际代码的情况下为您提供幼稚的策略。
对于任何位置 (x,y(,如果有四块相同颜色的棋子水平、垂直或对角线排列,则为赢家。 因此,让我们看看 RED 在水平方向上获胜的情况:
(x,y) (x+1,y) (x+2,y) (x+3,y)
RED RED RED RED
类似的坐标算术也适用于其他安排。 因此,您实际上只需要查看数组中从 (0,0( 到 (width-4,height-4( 的每个位置(除了在不同范围内操作的对角线情况之一(,并从该位置开始进行"获胜测试"。
更聪明的获胜测试只会检查最近播放的棋子周围的区域。
相关文章:
- valgrind-hellgrind与泄漏检查的结果不同
- C++模板来检查友元函数的存在
- 检查输入是否不是整数或数字
- 试图让变量检查数组中的某些内容
- 检查值是否在集合p1和p2中,但不在p3中
- C++概念:如何使用'concept'检查模板化结构的属性?
- 概念TS检查忽略私有访问修饰符
- 检查 std::shared_ptr<> 的当前底层类型是否为 T
- 在c++中检查长方体是否尽可能快地重叠(无迭代)
- 如何在C++中检查2D数组中负值的输入验证
- C++:正在检查LinkedList中的回文-递归方法-错误
- 使用for循环检查数组中的重复项
- 如何检查一个c++字符串中有多少相同的字符/数字
- 检查不带转换的扫描格式
- 如何检查线程是否锁定
- 清除前检查矢量
- 如何处理来自核心指南检查器的关于gsl::at的静态分析警告
- C++LDAP检查用户是否是特定组的成员
- 检查TCHAR数组输入是否为带符号整数C++
- 用概念检查属性的类型