Merge pull request #522 from noahmpauls/main

3D Tic Tac Toe in C#
This commit is contained in:
Jeff Atwood
2022-01-17 22:28:41 -08:00
committed by GitHub
3 changed files with 1761 additions and 0 deletions

View File

@@ -0,0 +1,10 @@
namespace ThreeDTicTacToe
{
class Program
{
static void Main()
{
new Qubic().Run();
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,559 @@
namespace ThreeDTicTacToe
{
/// <summary>
/// Data in this class was originally given by the following DATA section in
/// the BASIC program:
///
/// 2030 DATA 1,49,52,4,13,61,64,16,22,39,23,38,26,42,27,43
/// 2040 DATA 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20
/// 2050 DATA 21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38
/// 2060 DATA 39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56
/// 2070 DATA 57,58,59,60,61,62,63,64
/// 2080 DATA 1,17,33,49,5,21,37,53,9,25,41,57,13,29,45,61
/// 2090 DATA 2,18,34,50,6,22,38,54,10,26,42,58,14,30,46,62
/// 2100 DATA 3,19,35,51,7,23,39,55,11,27,43,59,15,31,47,63
/// 2110 DATA 4,20,36,52,8,24,40,56,12,28,44,60,16,32,48,64
/// 2120 DATA 1,5,9,13,17,21,25,29,33,37,41,45,49,53,57,61
/// 2130 DATA 2,6,10,14,18,22,26,30,34,38,42,46,50,54,58,62
/// 2140 DATA 3,7,11,15,19,23,27,31,35,39,43,47,51,55,59,63
/// 2150 DATA 4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,64
/// 2160 DATA 1,6,11,16,17,22,27,32,33,38,43,48,49,54,59,64
/// 2170 DATA 13,10,7,4,29,26,23,20,45,42,39,36,61,58,55,52
/// 2180 DATA 1,21,41,61,2,22,42,62,3,23,43,63,4,24,44,64
/// 2190 DATA 49,37,25,13,50,38,26,14,51,39,27,15,52,40,28,16
/// 2200 DATA 1,18,35,52,5,22,39,56,9,26,43,60,13,30,47,64
/// 2210 DATA 49,34,19,4,53,38,23,8,57,42,27,12,61,46,31,16
/// 2220 DATA 1,22,43,64,16,27,38,49,4,23,42,61,13,26,39,52
///
/// In short, each number is an index into the board. The data in this class
/// is zero-indexed, as opposed to the original data which was one-indexed.
/// </summary>
internal static class QubicData
{
/// <summary>
/// The corners and centers of the Qubic board. They correspond to the
/// following coordinates:
///
/// [
/// 111, 411, 414, 114, 141, 441, 444, 144,
/// 222, 323, 223, 322, 232, 332, 233, 333
/// ]
/// </summary>
public static readonly int[] CornersAndCenters = new int[16]
{
// (X) ( ) ( ) (X)
// ( ) ( ) ( ) ( )
// ( ) ( ) ( ) ( )
// (X) ( ) ( ) (X)
// ( ) ( ) ( ) ( )
// ( ) (X) (X) ( )
// ( ) (X) (X) ( )
// ( ) ( ) ( ) ( )
// ( ) ( ) ( ) ( )
// ( ) (X) (X) ( )
// ( ) (X) (X) ( )
// ( ) ( ) ( ) ( )
// (X) ( ) ( ) (X)
// ( ) ( ) ( ) ( )
// ( ) ( ) ( ) ( )
// (X) ( ) ( ) (X)
0,48,51,3,12,60,63,15,21,38,22,37,25,41,26,42
};
/// <summary>
/// A list of all "winning" rows in the Qubic board; that is, sets of
/// four spaces that, if filled entirely by the player (or machine),
/// would result in a win.
///
/// Each group of four rows in the list corresponds to a plane in the
/// cube, and each plane is organized so that the first and last rows
/// are on the plane's edges, while the second and third rows are in
/// the middle of the plane. The only exception is the last group of
/// rows, which contains the corners and centers rather than a plane.
///
/// The order of the rows in this list is key to how the Qubic AI
/// decides its next move.
/// </summary>
public static readonly int[,] RowsByPlane = new int[76, 4]
{
// (1) (1) (1) (1)
// (2) (2) (2) (2)
// (3) (3) (3) (3)
// (4) (4) (4) (4)
// ( ) ( ) ( ) ( )
// ( ) ( ) ( ) ( )
// ( ) ( ) ( ) ( )
// ( ) ( ) ( ) ( )
// ( ) ( ) ( ) ( )
// ( ) ( ) ( ) ( )
// ( ) ( ) ( ) ( )
// ( ) ( ) ( ) ( )
// ( ) ( ) ( ) ( )
// ( ) ( ) ( ) ( )
// ( ) ( ) ( ) ( )
// ( ) ( ) ( ) ( )
{ 0, 1, 2, 3, },
{ 4, 5, 6, 7, },
{ 8, 9, 10,11, },
{ 12,13,14,15, },
// ( ) ( ) ( ) ( )
// ( ) ( ) ( ) ( )
// ( ) ( ) ( ) ( )
// ( ) ( ) ( ) ( )
// (1) (1) (1) (1)
// (2) (2) (2) (2)
// (3) (3) (3) (3)
// (4) (4) (4) (4)
// ( ) ( ) ( ) ( )
// ( ) ( ) ( ) ( )
// ( ) ( ) ( ) ( )
// ( ) ( ) ( ) ( )
// ( ) ( ) ( ) ( )
// ( ) ( ) ( ) ( )
// ( ) ( ) ( ) ( )
// ( ) ( ) ( ) ( )
{ 16,17,18,19, },
{ 20,21,22,23, },
{ 24,25,26,27, },
{ 28,29,30,31, },
// ( ) ( ) ( ) ( )
// ( ) ( ) ( ) ( )
// ( ) ( ) ( ) ( )
// ( ) ( ) ( ) ( )
// ( ) ( ) ( ) ( )
// ( ) ( ) ( ) ( )
// ( ) ( ) ( ) ( )
// ( ) ( ) ( ) ( )
// (1) (1) (1) (1)
// (2) (2) (2) (2)
// (3) (3) (3) (3)
// (4) (4) (4) (4)
// ( ) ( ) ( ) ( )
// ( ) ( ) ( ) ( )
// ( ) ( ) ( ) ( )
// ( ) ( ) ( ) ( )
{ 32,33,34,35, },
{ 36,37,38,39, },
{ 40,41,42,43, },
{ 44,45,46,47, },
// ( ) ( ) ( ) ( )
// ( ) ( ) ( ) ( )
// ( ) ( ) ( ) ( )
// ( ) ( ) ( ) ( )
// ( ) ( ) ( ) ( )
// ( ) ( ) ( ) ( )
// ( ) ( ) ( ) ( )
// ( ) ( ) ( ) ( )
// ( ) ( ) ( ) ( )
// ( ) ( ) ( ) ( )
// ( ) ( ) ( ) ( )
// ( ) ( ) ( ) ( )
// (1) (1) (1) (1)
// (2) (2) (2) (2)
// (3) (3) (3) (3)
// (4) (4) (4) (4)
{ 48,49,50,51, },
{ 52,53,54,55, },
{ 56,57,58,59, },
{ 60,61,62,63, },
// (1) ( ) ( ) ( )
// (2) ( ) ( ) ( )
// (3) ( ) ( ) ( )
// (4) ( ) ( ) ( )
// (1) ( ) ( ) ( )
// (2) ( ) ( ) ( )
// (3) ( ) ( ) ( )
// (4) ( ) ( ) ( )
// (1) ( ) ( ) ( )
// (2) ( ) ( ) ( )
// (3) ( ) ( ) ( )
// (4) ( ) ( ) ( )
// (1) ( ) ( ) ( )
// (2) ( ) ( ) ( )
// (3) ( ) ( ) ( )
// (4) ( ) ( ) ( )
{ 0, 16,32,48, },
{ 4, 20,36,52, },
{ 8, 24,40,56, },
{ 12,28,44,60, },
// ( ) (1) ( ) ( )
// ( ) (2) ( ) ( )
// ( ) (3) ( ) ( )
// ( ) (4) ( ) ( )
// ( ) (1) ( ) ( )
// ( ) (2) ( ) ( )
// ( ) (3) ( ) ( )
// ( ) (4) ( ) ( )
// ( ) (1) ( ) ( )
// ( ) (2) ( ) ( )
// ( ) (3) ( ) ( )
// ( ) (4) ( ) ( )
// ( ) (1) ( ) ( )
// ( ) (2) ( ) ( )
// ( ) (3) ( ) ( )
// ( ) (4) ( ) ( )
{ 1, 17,33,49, },
{ 5, 21,37,53, },
{ 9, 25,41,57, },
{ 13,29,45,61, },
// ( ) ( ) (1) ( )
// ( ) ( ) (2) ( )
// ( ) ( ) (3) ( )
// ( ) ( ) (4) ( )
// ( ) ( ) (1) ( )
// ( ) ( ) (2) ( )
// ( ) ( ) (3) ( )
// ( ) ( ) (4) ( )
// ( ) ( ) (1) ( )
// ( ) ( ) (2) ( )
// ( ) ( ) (3) ( )
// ( ) ( ) (4) ( )
// ( ) ( ) (1) ( )
// ( ) ( ) (2) ( )
// ( ) ( ) (3) ( )
// ( ) ( ) (4) ( )
{ 2, 18,34,50, },
{ 6, 22,38,54, },
{ 10,26,42,58, },
{ 14,30,46,62, },
// ( ) ( ) ( ) (1)
// ( ) ( ) ( ) (2)
// ( ) ( ) ( ) (3)
// ( ) ( ) ( ) (4)
// ( ) ( ) ( ) (1)
// ( ) ( ) ( ) (2)
// ( ) ( ) ( ) (3)
// ( ) ( ) ( ) (4)
// ( ) ( ) ( ) (1)
// ( ) ( ) ( ) (2)
// ( ) ( ) ( ) (3)
// ( ) ( ) ( ) (4)
// ( ) ( ) ( ) (1)
// ( ) ( ) ( ) (2)
// ( ) ( ) ( ) (3)
// ( ) ( ) ( ) (4)
{ 3, 19,35,51, },
{ 7, 23,39,55, },
{ 11,27,43,59, },
{ 15,31,47,63, },
// (1) ( ) ( ) ( )
// (1) ( ) ( ) ( )
// (1) ( ) ( ) ( )
// (1) ( ) ( ) ( )
// (2) ( ) ( ) ( )
// (2) ( ) ( ) ( )
// (2) ( ) ( ) ( )
// (2) ( ) ( ) ( )
// (3) ( ) ( ) ( )
// (3) ( ) ( ) ( )
// (3) ( ) ( ) ( )
// (3) ( ) ( ) ( )
// (4) ( ) ( ) ( )
// (4) ( ) ( ) ( )
// (4) ( ) ( ) ( )
// (4) ( ) ( ) ( )
{ 0, 4, 8, 12, },
{ 16,20,24,28, },
{ 32,36,40,44, },
{ 48,52,56,60, },
// ( ) (1) ( ) ( )
// ( ) (1) ( ) ( )
// ( ) (1) ( ) ( )
// ( ) (1) ( ) ( )
// ( ) (2) ( ) ( )
// ( ) (2) ( ) ( )
// ( ) (2) ( ) ( )
// ( ) (2) ( ) ( )
// ( ) (3) ( ) ( )
// ( ) (3) ( ) ( )
// ( ) (3) ( ) ( )
// ( ) (3) ( ) ( )
// ( ) (4) ( ) ( )
// ( ) (4) ( ) ( )
// ( ) (4) ( ) ( )
// ( ) (4) ( ) ( )
{ 1, 5, 9, 13, },
{ 17,21,25,29, },
{ 33,37,41,45, },
{ 49,53,57,61, },
// ( ) ( ) (1) ( )
// ( ) ( ) (1) ( )
// ( ) ( ) (1) ( )
// ( ) ( ) (1) ( )
// ( ) ( ) (2) ( )
// ( ) ( ) (2) ( )
// ( ) ( ) (2) ( )
// ( ) ( ) (2) ( )
// ( ) ( ) (3) ( )
// ( ) ( ) (3) ( )
// ( ) ( ) (3) ( )
// ( ) ( ) (3) ( )
// ( ) ( ) (4) ( )
// ( ) ( ) (4) ( )
// ( ) ( ) (4) ( )
// ( ) ( ) (4) ( )
{ 2, 6, 10,14, },
{ 18,22,26,30, },
{ 34,38,42,46, },
{ 50,54,58,62, },
// ( ) ( ) ( ) (1)
// ( ) ( ) ( ) (1)
// ( ) ( ) ( ) (1)
// ( ) ( ) ( ) (1)
// ( ) ( ) ( ) (2)
// ( ) ( ) ( ) (2)
// ( ) ( ) ( ) (2)
// ( ) ( ) ( ) (2)
// ( ) ( ) ( ) (3)
// ( ) ( ) ( ) (3)
// ( ) ( ) ( ) (3)
// ( ) ( ) ( ) (3)
// ( ) ( ) ( ) (4)
// ( ) ( ) ( ) (4)
// ( ) ( ) ( ) (4)
// ( ) ( ) ( ) (4)
{ 3, 7, 11,15, },
{ 19,23,27,31, },
{ 35,39,43,47, },
{ 51,55,59,63, },
// (1) ( ) ( ) ( )
// ( ) (1) ( ) ( )
// ( ) ( ) (1) ( )
// ( ) ( ) ( ) (1)
// (2) ( ) ( ) ( )
// ( ) (2) ( ) ( )
// ( ) ( ) (2) ( )
// ( ) ( ) ( ) (2)
// (3) ( ) ( ) ( )
// ( ) (3) ( ) ( )
// ( ) ( ) (3) ( )
// ( ) ( ) ( ) (3)
// (4) ( ) ( ) ( )
// ( ) (4) ( ) ( )
// ( ) ( ) (4) ( )
// ( ) ( ) ( ) (4)
{ 0, 5, 10,15, },
{ 16,21,26,31, },
{ 32,37,42,47, },
{ 48,53,58,63, },
// ( ) ( ) ( ) (1)
// ( ) ( ) (1) ( )
// ( ) (1) ( ) ( )
// (1) ( ) ( ) ( )
// ( ) ( ) ( ) (2)
// ( ) ( ) (2) ( )
// ( ) (2) ( ) ( )
// (2) ( ) ( ) ( )
// ( ) ( ) ( ) (3)
// ( ) ( ) (3) ( )
// ( ) (3) ( ) ( )
// (3) ( ) ( ) ( )
// ( ) ( ) ( ) (4)
// ( ) ( ) (4) ( )
// ( ) (4) ( ) ( )
// (4) ( ) ( ) ( )
{ 12,9, 6, 3, },
{ 28,25,22,19, },
{ 44,41,38,35, },
{ 60,57,54,51, },
// (1) (2) (3) (4)
// ( ) ( ) ( ) ( )
// ( ) ( ) ( ) ( )
// ( ) ( ) ( ) ( )
// ( ) ( ) ( ) ( )
// (1) (2) (3) (4)
// ( ) ( ) ( ) ( )
// ( ) ( ) ( ) ( )
// ( ) ( ) ( ) ( )
// ( ) ( ) ( ) ( )
// (1) (2) (3) (4)
// ( ) ( ) ( ) ( )
// ( ) ( ) ( ) ( )
// ( ) ( ) ( ) ( )
// ( ) ( ) ( ) ( )
// (1) (2) (3) (4)
{ 0, 20,40,60, },
{ 1, 21,41,61, },
{ 2, 22,42,62, },
{ 3, 23,43,63, },
// ( ) ( ) ( ) ( )
// ( ) ( ) ( ) ( )
// ( ) ( ) ( ) ( )
// (1) (2) (3) (4)
// ( ) ( ) ( ) ( )
// ( ) ( ) ( ) ( )
// (1) (2) (3) (4)
// ( ) ( ) ( ) ( )
// ( ) ( ) ( ) ( )
// (1) (2) (3) (4)
// ( ) ( ) ( ) ( )
// ( ) ( ) ( ) ( )
// (1) (2) (3) (4)
// ( ) ( ) ( ) ( )
// ( ) ( ) ( ) ( )
// ( ) ( ) ( ) ( )
{ 48,36,24,12, },
{ 49,37,25,13, },
{ 50,38,26,14, },
{ 51,39,27,15, },
// (1) ( ) ( ) ( )
// (2) ( ) ( ) ( )
// (3) ( ) ( ) ( )
// (4) ( ) ( ) ( )
// ( ) (1) ( ) ( )
// ( ) (2) ( ) ( )
// ( ) (3) ( ) ( )
// ( ) (4) ( ) ( )
// ( ) ( ) (1) ( )
// ( ) ( ) (2) ( )
// ( ) ( ) (3) ( )
// ( ) ( ) (4) ( )
// ( ) ( ) ( ) (1)
// ( ) ( ) ( ) (2)
// ( ) ( ) ( ) (3)
// ( ) ( ) ( ) (4)
{ 0, 17,34,51, },
{ 4, 21,38,55, },
{ 8, 25,42,59, },
{ 12,29,46,63, },
// ( ) ( ) ( ) (1)
// ( ) ( ) ( ) (2)
// ( ) ( ) ( ) (3)
// ( ) ( ) ( ) (4)
// ( ) ( ) (1) ( )
// ( ) ( ) (2) ( )
// ( ) ( ) (3) ( )
// ( ) ( ) (4) ( )
// ( ) (1) ( ) ( )
// ( ) (2) ( ) ( )
// ( ) (3) ( ) ( )
// ( ) (4) ( ) ( )
// (1) ( ) ( ) ( )
// (2) ( ) ( ) ( )
// (3) ( ) ( ) ( )
// (4) ( ) ( ) ( )
{ 48,33,18,3, },
{ 52,37,22,7, },
{ 56,41,26,11, },
{ 60,45,30,15, },
// (1) ( ) ( ) (3)
// ( ) ( ) ( ) ( )
// ( ) ( ) ( ) ( )
// (4) ( ) ( ) (2)
// ( ) ( ) ( ) ( )
// ( ) (1) (3) ( )
// ( ) (4) (2) ( )
// ( ) ( ) ( ) ( )
// ( ) ( ) ( ) ( )
// ( ) (2) (4) ( )
// ( ) (3) (1) ( )
// ( ) ( ) ( ) ( )
// (2) ( ) ( ) (4)
// ( ) ( ) ( ) ( )
// ( ) ( ) ( ) ( )
// (3) ( ) ( ) (1)
{ 0, 21,42,63, },
{ 15,26,37,48, },
{ 3, 22,41,60, },
{ 12,25,38,51, },
};
}
}