循环通过二维数组与随机板大小对角线
Loop through 2D array diagonally with random board size
我想知道如何循环通过一个二维数组,如果数组的大小是随机的,例如6x6或10x10等。这个想法是搜索四个相同类型的字符,'x'或'o'。这通常是桌面游戏所需要的。
int main() {
int array_size = 5; // Size of array
int array_height = array_size;
bool turn = true; // true = player 1, false = player 2
bool there_is_a_winner = false;
char** p_connect_four = new char*[array_size];
for (int i = 0; i < array_size; i++) // Initialise the 2D array
{ // At the same time set a value "_" as blank field
p_connect_four[i] = new char[array_size];
for (int j = 0; j < array_size; j++) {
p_connect_four[i][j] = '_';
}
}
}
这是我目前得到的,检查从[3][0]到[0][3]。但这需要我添加两个for循环来检查[4][0]到[0][4]和[4][1]到[1][4],如果棋盘的大小是5x5。
for (int i = 3, j = 0; i > 0 && j < array_size; i--, j++ ) {// CHECK DOWN up right from 3,0 -> 0,3
if (p_connect_four[i][j] == p_connect_four[i - 1][j + 1] && p_connect_four[i][j] != '_' ) {
check_diagonalRight++;
if (check_diagonalRight == 3) {
there_is_a_winner = true;
break;
}
}
else {
check_diagonalRight = 0;
}
}
if (there_is_a_winner) { // Break while loop of game.
break;
}
很明显,我想检查整个棋盘对角线向右不管棋盘的大小。除了使用3个单独的for循环进行检查之外,还有其他方法吗[3][0] ->[0][3],[4][0] ->[0][4]和[4][1]->[1][4]吗?
for (i = array_size - 1, j = array_size - 2;
i < array_size && i >= 0, j < array_size && j >= 0; j--)
{ // starts from [4][3] and loops to the left if arraysize = 5x5
// but works on any size
int k = i, l = j;
for (k, l; k < array_size && k > 0, l < array_size && l > 0; k--, l++)
{ // checks diagonally to the right
if (check_diagonalRight == 3)
{
there_is_a_winner = true;
break;
}
if (p_connect_four[k][l] == p_connect_four[k - 1][l + 1] &&
p_connect_four[k][l] != '_')
{ //check up one square and right one square
check_diagonalRight++;
}
else
{
check_diagonalRight = 0;
// if its not equal, reset counter.
}
}
if (there_is_a_winner)
{
break; // break for loop
}
}
if (there_is_a_winner)
{
break; // break while loop of game
}
无论大小如何,这都可以检查正确,也可以为其他角度实现它,并且它将适用于任何板尺寸。您可以使用嵌套循环同时检查左右对角线。
这将完美地为您的程序工作!我希望如此!
int arraySize = 8;
for(int i=0, j=0; i<arraySize && j<arraySize; i++, j++)
{
if((i == 0 && j == 0) || (i == arraySize - 1 && j == arraySize - 1))
{
continue;
}
else
{
int k = i;
int l = j;
//This Loop will check from central line (principal diagonal) to up right side (like slash sign / (representing direction))
for(k, l; k>0 && l < arraySize - 1; k--, l++)
{
//Here check your condition and increment to your variable. like:
if (p_connect_four[k][l] == p_connect_four[k - 1][l + 1] && p_connect_four[k][l] != '_' )
{
check_diagonalRight++;
}
}
//You can break the loop here if check_diagonalRight != k then break
k = i;
l = j;
//This Loop will check from central line (principal diagonal) to down left side (like slash sign / (representing direction))
for(k, l; k<arraySize - 1 && l > 0; k++, l--)
{
//Here check your condition and increment to your variable. like:
if (p_connect_four[k][l] == p_connect_four[k + 1][l - 1] && p_connect_four[k][l] != '_' )
{
check_diagonalRight++;
}
}
if(check_diagonalRight == i+j+1)
{
there_is_a_winner = true;
break;
}
}
}
我建议用额外的特殊情况包围你的板,以避免检查边界。
为了测试每个方向,我建议使用一个偏移数组来应用。
下面可能有帮助:
#include <vector>
using board_t = std::vector<std::vector<char>>;
constexpr const std::size_t MaxAlignment = 4;
enum Case {
Empty = '_',
X = 'X',
O = 'O',
Bound = '.'
};
enum class AlignmentResult { X, O, None };
// Create a new board, valid index would be [1; size] because of surrounding.
board_t new_board(std::size_t size)
{
// Create an empty board
board_t board(size + 2, std::vector<char>(size + 2, Case::Empty));
// Add special surround.
for (std::size_t i = 0; i != size + 2; ++i) {
board[0][i] = Case::Bound;
board[size + 1][i] = Case::Bound;
board[i][0] = Case::Bound;
board[i][size + 1] = Case::Bound;
}
return board_t;
}
// Test a winner from position in given direction.
AlignmentResult test(
const board_t& board,
std::size_t x, std::size_t y,
int offset_x, int offset_y)
{
if (board[x][y] == Case::Empty) {
return AlignmentResult::None;
}
for (std::size_t i = 1; i != MaxAlignment; ++i) {
// Following condition fails when going 'out of bound' thanks to Case::Bound,
// else you have also to check size...
if (board[x][y] != board[x + i * offset_x][y + i * offset_y]) {
return AlignmentResult::None;
}
}
if (board[x][y] == Case::X) {
return AlignmentResult::X;
} else {
return AlignmentResult::O;
}
}
// Test a winner on all the board
AlignmentResult test(const board_t& board)
{
// offset for direction. Use only 4 direction because of the symmetry.
const int offsets_x[] = {1, 1, 1, 0};
const int offsets_y[] = {-1, 0, 1, 1};
const std::size_t size = board.size() - 1;
for (std::size_t x = 1; x != size; ++x) {
for (std::size_t y = 1; y != size; ++y) {
for (std::size_t dir = 0; dir != 4; ++dir) { // for each directions
auto res = test(board, x, y, offsets_x[dir], offsets_y[y]);
if (res != AlignmentResult::None) {
return res;
}
}
}
}
return AlignmentResult::None;
}
相关文章:
- 为什么随机数生成器不在void函数中随机化数字,而在main函数中随机化
- 为什么 Serial.println(<char[]>);返回随机字符?
- 字符串-C++后显示的随机字符
- 循环中的随机函数
- 在c++构造函数中使用随机字符串生成器
- 使用std::mt19937从字符串中返回一个随机单词
- 为什么std::condition_variable notify_all的工作速度比notify_one快(对于随机请
- 如何在C++中高效地构造随机骰子
- 在类中使用随机生成器时出现性能问题
- 如何在cuSparse中得到稀疏矩阵的对角线
- 在将数字随机生成为数组期间从内存输出随机数的数组
- 如何打印数组对角线的一侧
- 将字符随机转换为大写的函数
- 为什么 vector 的随机访问迭代器给出与指针不同的内存地址?
- 如何生成一个随机的 n 位数,其中 n 是任意的
- 将随机生成的数字添加到数组 + 对这些数组求平均值
- 如何使用要传递给 mt19937 的可选随机种子参数设计函数
- 在C++中随机生成 20 个非重复数字
- 检查 2D 网格的某个元素是否与另一个元素共享对角线、水平线或垂直线
- 循环通过二维数组与随机板大小对角线