-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmake7.h
148 lines (122 loc) · 11.2 KB
/
make7.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
/*
Copyright (C) 2020- TheTrustedComputer
This is a computer implementation of Make 7, a Connect 4-like game involving elementary additon.
The objective of this game is to drop numbers that add up to seven in a vertical, horizontal, or diagonal matter.
The physical game ships 11 one tiles, 11 two tiles, and 4 three tiles per player, totaling 52 tiles.
This structure enforces them so that when any player runs out of tiles, they may not drop any more of them.
Below is a visual illustration on how the playing board is represented internally inside this data structure:
Playing board Player 1 Player 2 One tiles* Two tiles Three tiles
. . . . . . . 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
. . * . * . . 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
. * . (2) . * . 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0
. . . (3) . . . 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0
* . . (1)[1] . (3) 0 0 0 0 1 0 0 0 0 0 1 0 0 1 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
. . [2](1)[2] . [1] 0 0 1 0 1 0 1 0 0 0 1 0 0 0 0 0 0 1 0 0 1 0 0 1 0 1 0 0 0 0 0 0 0 0 0
. (2)[1][2][1](1)[2] 0 0 1 1 1 0 1 0 1 0 0 0 1 0 0 0 1 0 1 1 0 0 1 0 1 0 0 1 0 0 0 0 0 0 0
Sym Description * Storing one tiles are not required and can be computed with this statement:
[1] | Player 1's tiles * One_Tiles = (Player1_Tiles | Player2_Tiles) ^ (Two_Tiles | Three_Tiles);
(1) | Player 2's tiles
. | Empty (1, 2)
* | Empty (1, 2, 3)
*/
// Header guards
#ifndef MAKE7_H
#define MAKE7_H
#include <stdio.h>
#include <stdint.h>
// MinGW does not have C23's stdbit.h header
#if !(defined(__MINGW32__) || defined(__MINGW64__))
#include <stdbit.h>
#endif
// Make 7's board dimensions is a fixed seven-by-seven square to take into account of the one tiles.
#define MAKE7_SIZE 7
#define MAKE7_SIZE_M1 6
#define MAKE7_SIZE_P1 8
#define MAKE7_SIZE_P2 9
#define MAKE7_SIZE_X3 21
#define MAKE7_AREA 49
#define MAKE7_AREA_P1 50
#define MAKE7_AREA_X2 98
// Make 7 static bitmaps; it works pretty much more or less the same as any Connect Four implementation.
#define MAKE7_ALL 0x7f7f7f7f7f7f7full
#define MAKE7_BOT 0x1010101010101ull
#define MAKE7_TOP 0x80808080808080ull
#define MAKE7_LCL 0x7full
// In the physical game, the three tiles can only be dropped at the marked red squares; ones and twos can drop anywhere.
#define MAKE7_THREES 0x4102008201004ull
// The players are named Green and Yellow after the included colored tiles for convenience.
#define MAKE7_P1_NAME "Green"
#define MAKE7_P2_NAME "Yellow"
// Global temporary storage locations or buffers for the number tiles from user input.
static uint8_t g_userNumberTile, g_inputReadyFlag;
// Whether to swap the tile colors in the output.
static bool g_swapColors;
// Vertical bitmask table to search for vertical connections below this tile, including itself
static const uint64_t VERT_BITMASK_TABLE[55] = {0x1ull, 0x3ull, 0x7ull, 0xfull, 0x1full, 0x3full, 0x7full, 0x0ull,
0x100ull, 0x300ull, 0x700ull, 0xf00ull, 0x1f00ull, 0x3f00ull, 0x7f00ull, 0x0ull,
0x10000ull, 0x30000ull, 0x70000ull, 0xf0000ull, 0x1f0000ull, 0x3f0000ull, 0x7f0000ull, 0x0ull,
0x1000000ull, 0x3000000ull, 0x7000000ull, 0xf000000ull, 0x1f000000ull, 0x3f000000ull, 0x7f000000ull, 0x0ull,
0x100000000ull, 0x300000000ull, 0x700000000ull, 0xf00000000ull, 0x1f00000000ull, 0x3f00000000ull, 0x7f00000000ull, 0x0ull,
0x10000000000ull, 0x30000000000ull, 0x70000000000ull, 0xf0000000000ull, 0x1f0000000000ull, 0x3f0000000000ull, 0x7f0000000000ull, 0x0ull,
0x1000000000000ull, 0x3000000000000ull, 0x7000000000000ull, 0xf000000000000ull, 0x1f000000000000ull, 0x3f000000000000ull, 0x7f000000000000ull};
// Positive-slope diagonal bitmask table as above
static const uint64_t PDIAG_BITMASK_TABLE[55] = {0x40201008040201ull, 0x402010080402ull, 0x4020100804ull, 0x40201008ull, 0x402010ull, 0x4020ull, 0x40ull, 0x0ull,
0x20100804020100ull, 0x40201008040201ull, 0x402010080402ull, 0x4020100804ull, 0x40201008ull, 0x402010ull, 0x4020ull, 0x0ull,
0x10080402010000ull, 0x20100804020100ull, 0x40201008040201ull, 0x402010080402ull, 0x4020100804ull, 0x40201008ull, 0x402010ull, 0x0ull,
0x8040201000000ull, 0x10080402010000ull, 0x20100804020100ull, 0x40201008040201ull, 0x402010080402ull, 0x4020100804ull, 0x40201008ull, 0x0ull,
0x4020100000000ull, 0x8040201000000ull, 0x10080402010000ull, 0x20100804020100ull, 0x40201008040201ull, 0x402010080402ull, 0x4020100804ull, 0x0ull,
0x2010000000000ull, 0x4020100000000ull, 0x8040201000000ull, 0x10080402010000ull, 0x20100804020100ull, 0x40201008040201ull, 0x402010080402ull, 0x0ull,
0x1000000000000ull, 0x2010000000000ull, 0x4020100000000ull, 0x8040201000000ull, 0x10080402010000ull, 0x20100804020100ull, 0x40201008040201ull};
// Negative-slope diagonals
static const uint64_t NDIAG_BITMASK_TABLE[55] = {0x1ull, 0x102ull, 0x10204ull, 0x1020408ull, 0x102040810ull, 0x10204081020ull, 0x1020408102040ull, 0x0ull,
0x102ull, 0x10204ull, 0x1020408ull, 0x102040810ull, 0x10204081020ull, 0x1020408102040ull, 0x2040810204000ull, 0x0ull,
0x10204ull, 0x1020408ull, 0x102040810ull, 0x10204081020ull, 0x1020408102040ull, 0x2040810204000ull, 0x4081020400000ull, 0x0ull,
0x1020408ull, 0x102040810ull, 0x10204081020ull, 0x1020408102040ull, 0x2040810204000ull, 0x4081020400000ull, 0x8102040000000ull, 0x0ull,
0x102040810ull, 0x10204081020ull, 0x1020408102040ull, 0x2040810204000ull, 0x4081020400000ull, 0x8102040000000ull, 0x10204000000000ull, 0x0ull,
0x10204081020ull, 0x1020408102040ull, 0x2040810204000ull, 0x4081020400000ull, 0x8102040000000ull, 0x10204000000000ull, 0x20400000000000ull, 0x0ull,
0x1020408102040ull, 0x2040810204000ull, 0x4081020400000ull, 0x8102040000000ull, 0x10204000000000ull, 0x20400000000000ull, 0x40000000000000ull};
// Bitmask of adjacent tiles; below is a sample illustration:
// 1 1 1
// 1 0 1
// 1 1 1
static const uint64_t ADJ_BITMASK_TABLE[55] = {0x302ull, 0x705ull, 0xe0aull, 0x1c14ull, 0x3828ull, 0x7050ull, 0x6020ull, 0x0ull,
0x30203ull, 0x70507ull, 0xe0a0eull, 0x1c141cull, 0x382838ull, 0x705070ull, 0x602060ull, 0x0ull,
0x3020300ull, 0x7050700ull, 0xe0a0e00ull, 0x1c141c00ull, 0x38283800ull, 0x70507000ull, 0x60206000ull, 0x0ull,
0x302030000ull, 0x705070000ull, 0xe0a0e0000ull, 0x1c141c0000ull, 0x3828380000ull, 0x7050700000ull, 0x6020600000ull, 0x0ull,
0x30203000000ull, 0x70507000000ull, 0xe0a0e000000ull, 0x1c141c000000ull, 0x382838000000ull, 0x705070000000ull, 0x602060000000ull, 0x0ull,
0x3020300000000ull, 0x7050700000000ull, 0xe0a0e00000000ull, 0x1c141c00000000ull, 0x38283800000000ull, 0x70507000000000ull, 0x60206000000000ull, 0x0ull,
0x302030000000000ull, 0x705070000000000ull, 0xe0a0e0000000000ull, 0x1c141c0000000000ull, 0x3828380000000000ull, 0x7050700000000000ull, 0x6020600000000000ull};
// Direction tables to check for adjacent tiles
static const uint8_t DIRECTION_TABLE[4] = {1, MAKE7_SIZE_P1, MAKE7_SIZE, MAKE7_SIZE_P2};
// The core Make 7 structure in which all movements and calculations are performed here.
typedef struct
{
uint64_t player[2], tiles23[2]; // The bitmap of each player's number tiles and all dropped tiles except 1s.
uint8_t height[MAKE7_SIZE]; // The bit position of the height of each column of the grid.
uint8_t remaining[3]; // The remaining tiles for each player: lower 4 bits => P1; upper 4 bits => P2
uint8_t lastTile; // A variable to store the last dropped tile by the current player.
bool turn; // The current player's turn: False = Player 1; True = Player 2.
}
Make7;
// Memory and I/O
void Make7_initialize(Make7*); // Resets the Make 7 data structure to the initial position.
void Make7_print(const Make7*); // Prints the board of number tiles and their amount to the console.
// Logical functions
bool Make7_tilesSumTo7(const Make7*); // Returns true if the board configuration has an arrangement of tiles that sums to at least seven.
bool Make7_gameOver(const Make7*); // Tests if the game is over, i.e. a player has a winning alignment or neither have any tiles left.
bool Make7_noMoreMoves(const Make7*); // True when the current player to move has no more legal moves and false otherwise.
uint8_t Make7_plyNum(const Make7*); // Counts the number of plies or half-moves using population count.
bool Make7_gridFull(const Make7*); // Another draw condition is when the grid becomes full if either player has tiles left.
// Move functions
bool Make7_drop(Make7*, const uint8_t, const uint8_t); // Drops a number tile to a column as long as that column is not full.
// void Make7_undrop(Make7*); // Undos the dropping of number tiles--used only during search.
// User input functions
bool Make7_getUserInput(Make7*, const char); // Performs a move from user input. Numbers specify what tile to use and letters what column to drop.
bool Make7_sequence(Make7*, const char*); // Perform moves from a string of characters. This is used when the user chooses to pass them as arguments.
// Other functions
uint64_t Make7_hashEncode(const Make7*); // Encodes a hashed Make 7 position for use in the transposition table.
uint64_t Make7_reverse(uint64_t); // Returns the horizontal inversion of a Make 7 grid bitboard.
bool Make7_symmetrical(const Make7*); // Is the board's left side the same as its right side when flipped horizontally?
void Make7_generate(const Make7*, uint8_t*, uint8_t*); // Generates all possible drop moves for the current player.
void Make7_helpMessage(const char*); // Prints a help message to the console.
#endif /* MAKE7_H */