对于随机抽动的tic-tac-toe游戏模拟器,我需要利用2D阵列来模拟2个玩家之间的回合。为了填充数组,我一直在使用一个简单的随机数生成器来生成0到1之间的随机数。
//create 2D array
const int ROWS = 3;
const int COLS = 3;
int[,] tictactoeArray = new int[ROWS, COLS];
//create random variable
Random rand = new Random();
//method to fill array with random values between 0 and 1.
private void RandomizeArray(ref int[,] iArray)
{
for (int row = 0; row < ROWS; row++)
{
for (int col = 0; col < COLS; col++)
{
tictactoeArray[row, col] = rand.Next(2);
}
}
}
但是当我使用这样的随机数生成器时,我偶尔会得到与tic-tac-toe相关的不可能的值组合。因为价值1将发生6次或更多次,并使游戏对另一个“玩家”不公平。我已经进行了大量的搜索,但还没有找到一种方法(或多或少)均匀地分配2个值。有什么建议吗?
答案 0 :(得分:2)
你需要模拟玩家的回合。而不是随机生成1或2,您可以按照以下算法假设
0. initialize all 9 positions with 0 on tic-tac-toe board
1. select a number between 0 to 8 randomly. ( which denotes one of 9 positions)
2. put 1 in that position
3. select another number between 0 to 8 randomly ( if it collides with number previously selected pull other random number.
4. put 2 in that position.
5. repeat till all the 9 positions are filled.
方法2 ..
create a Linked list of 9 numbers (from 1 to 9).
draw a number (name it x) between 1 to size of the Set ( which will be 9 for first draw)
read the value at the position 'x' and put 1 in that position
remove the element at position x
draw another number x ( between 1 to 8 this time ) and put 2 in that position.
remove the element at position x.
keep doing till linked list is empty.
答案 1 :(得分:0)
问题标题的字面答案是这样的:
var random = new Random();
var randomValues = new[] { 0, 0, 0, 0, 0, 1, 1, 1, 1, 1 } // enough values to fill board
.Select(x => new { Weight = random.Next(), Value = x }) // add random weight
.OrderBy(x => x.Weight) // order by weight to create random sort
.Take(9) // only need 9 of the 10 values
.ToList();
var ticTacToeBoard = new int[3, 3];
var index = 0;
for (int row = 0; row < 3; row++) // fill the two-dimensional array
{
for (int column = 0; column < 3; column++)
{
ticTacToeBoard[row, column] = randomValues[index].Value;
index++;
}
}
大多数时候,这个&#34;随机而无需替换&#34;技术将导致一个可能的结束游戏板,但是,你偶尔会得到一个连续3个零和 3个游戏的游戏板,这将是无效的。要解决这个问题,你可以将上面的代码放在一个循环中,只有在有效游戏板的情况下才退出循环。
那就是说,我同意@ meetthakkar实际模拟游戏的方法对这个特定问题更有意义。
答案 2 :(得分:0)
在一维数组中预先创建x和o然后随机随机地移动它似乎更简单
//Both X and O always get at least 4 moves
List<int> common = new List<int> { 0, 0, 0, 0, 1, 1, 1, 1 };
//Either X or O gets a 5th move, make this equally likely
Random rand = new Random();
common.Add(rand.Next(0, 2));
//Randomly shuffle the X's and O's, this creates a completed tic tac toe board
//This can have more than one winner since we aren't stopping when someone wins
//as would normally be done
var randomBoard = common.OrderBy(x => rand.Next()).ToArray();
//Convert to a 2 dimensional array if desired
int[,] twoDRandomBoard = new int[3, 3];
for (int i = 0; i < randomBoard.Length; i++)
twoDRandomBoard[i / 3, i%3] = randomBoard[i];
你最终会得到一些有两个“赢家”的董事会,但如果你认为整个董事会已满,这就是你在问题中所表现出来的方式。如果你想在某人获胜后停止,那么这将是不同的,但这将适用于随机完整的董事会。
答案 3 :(得分:0)
好吧,我可能有点困惑,但是从那个开始填充1或0表示的井字棋盘是没有意义的,可能是1或2。
建议执行以下操作:
private static ThreadLocal<Random> rand = new ThreadLocal<Random>(()=>new Random());
const int PLAYER_ONE = 1;
const int PLAYER_TWO = 2;
//color decided by who goes first in tic-tac-toe?
private static int playingColor;
private static void PlayRound(int[][] board)
{
var playableCoords = new List<Tuple<int,int>>();
for(int x=0;x<board.Length;x++)
for(int y=0;y<board[x].Length;y++)
if(board[x][y] == 0)
playableCoords.Add(Tuple.Create(x,y));
//check for a terminal board state before you do this method
if(!playableCoords.Any()) return;
var randm = rand.Value;
var vl = playableCoords[ randm.Next(playableCoords.Count - 1) ];
board[vl.Item1][vl.Item2] = playingColor ;
}
有更有效的方法可以做到这一点,如果你正在处理一个有很多可能组合的棋盘,那么我会建议保留一个可用位置的记录并从那里开始,但是对于一个3x3游戏看不到需要这样做。
如果您想要这样做直到它已满,请执行以下操作:
var board = new int[3][3];
for(int i=0;i<9;i++)
{
playingColor = (i%1)+1;
PlayRound(board);
}
对我来说没有意义,但这就是你如何模拟游戏。
答案 4 :(得分:0)
void RandomizeArray(ref int[,] iArray)
{
for (int row = 0; row < ROWS; row++)
{
for (int col = 0; col < COLS; col++)
{
Random rand = new Random();
tictactoeArray[row, col] = rand.Next(2);
}
}
}
请将Random rand = new Random()
放入功能正文中。
每次制作一个新兰特时可能会更好。