Yet Another Tic Tac Toe for Pokitto

Dependencies:   PokittoLib mbed-src

Committer:
HomineLudens
Date:
Wed Oct 04 09:03:13 2017 +0000
Revision:
1:cdc038225cf5
Parent:
0:a92a22490aaa
YATT ok

Who changed what in which revision?

UserRevisionLine numberNew contents of line
HomineLudens 0:a92a22490aaa 1 #include "Pokitto.h"
HomineLudens 0:a92a22490aaa 2
HomineLudens 0:a92a22490aaa 3 #define CELL_SIZE 32
HomineLudens 0:a92a22490aaa 4 #define SIGN_SIZE 20
HomineLudens 0:a92a22490aaa 5 #define CURSOR_SIZE 36
HomineLudens 0:a92a22490aaa 6
HomineLudens 0:a92a22490aaa 7 #define MAX_GRID_SIZE 10
HomineLudens 0:a92a22490aaa 8
HomineLudens 0:a92a22490aaa 9 #define MAX_PLAYERS 4
HomineLudens 0:a92a22490aaa 10 #define MAX_MENU_SETTINGS 7
HomineLudens 0:a92a22490aaa 11
HomineLudens 0:a92a22490aaa 12 #define PI2 PI/2.0
HomineLudens 0:a92a22490aaa 13 #define PI4 PI/4.0
HomineLudens 0:a92a22490aaa 14 #define PI3_4 PI*3.0/4.0
HomineLudens 0:a92a22490aaa 15
HomineLudens 0:a92a22490aaa 16 const uint8_t logo[] = {
HomineLudens 0:a92a22490aaa 17 188,38,
HomineLudens 0:a92a22490aaa 18 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,
HomineLudens 0:a92a22490aaa 19 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,
HomineLudens 0:a92a22490aaa 20 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,
HomineLudens 0:a92a22490aaa 21 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,
HomineLudens 0:a92a22490aaa 22 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,
HomineLudens 0:a92a22490aaa 23 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,
HomineLudens 0:a92a22490aaa 24 0,0,0,0,0,0,21,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,
HomineLudens 0:a92a22490aaa 25 0,0,0,0,0,0,21,64,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,
HomineLudens 0:a92a22490aaa 26 0,0,0,0,0,0,21,64,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,
HomineLudens 0:a92a22490aaa 27 0,0,0,0,0,0,5,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,
HomineLudens 0:a92a22490aaa 28 0,0,0,0,0,64,0,0,0,0,0,0,0,0,0,0,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,0,0,0,0,0,0,0,0,
HomineLudens 0:a92a22490aaa 29 0,1,85,85,85,64,0,0,0,0,0,0,0,0,0,0,85,85,85,80,1,0,0,0,0,0,0,0,0,0,0,0,1,85,85,85,64,0,0,0,0,0,0,0,0,0,0,
HomineLudens 0:a92a22490aaa 30 0,5,85,85,85,0,85,0,0,5,85,80,0,0,0,1,85,85,85,64,21,64,0,0,0,0,21,85,64,0,0,0,5,85,85,85,0,21,85,0,0,0,5,85,0,0,0,
HomineLudens 0:a92a22490aaa 31 0,21,85,85,64,1,85,0,0,21,85,84,0,0,0,5,85,85,80,0,85,80,0,0,0,1,85,85,64,0,0,0,21,85,85,64,0,85,85,80,0,0,85,85,64,0,0,
HomineLudens 0:a92a22490aaa 32 0,80,5,80,0,0,85,0,1,80,5,84,0,0,0,20,1,84,0,0,5,84,0,0,0,5,64,85,64,0,0,0,80,5,80,0,1,85,85,84,0,1,80,21,80,0,0,
HomineLudens 0:a92a22490aaa 33 0,0,5,64,0,0,21,0,1,64,0,0,0,0,0,0,1,80,0,0,1,85,0,0,0,20,0,0,0,0,0,0,0,5,64,0,5,64,5,85,0,5,64,5,80,0,0,
HomineLudens 0:a92a22490aaa 34 0,0,5,64,0,0,21,0,5,0,0,0,0,0,0,0,1,80,0,0,0,85,64,0,0,84,0,0,0,0,0,0,0,5,64,0,5,0,0,85,64,21,0,5,64,0,0,
HomineLudens 0:a92a22490aaa 35 0,0,5,64,0,0,21,0,21,0,0,0,0,0,0,0,1,80,0,0,0,21,80,0,0,84,0,0,0,0,0,0,0,5,64,0,21,0,0,21,80,20,0,85,85,84,0,
HomineLudens 0:a92a22490aaa 36 0,0,5,64,0,0,21,0,21,0,0,0,0,0,0,0,1,80,0,0,0,21,80,0,0,80,0,0,0,0,0,0,0,5,64,0,21,0,0,5,80,85,85,85,85,80,0,
HomineLudens 0:a92a22490aaa 37 0,0,5,64,0,0,21,0,21,0,0,0,0,0,0,0,1,80,0,0,0,85,84,0,1,80,0,0,0,0,0,0,0,5,64,0,21,0,0,5,80,85,85,85,85,64,0,
HomineLudens 0:a92a22490aaa 38 0,0,5,64,0,0,21,0,21,0,0,0,0,0,0,0,1,80,0,0,1,65,85,0,1,80,0,0,0,0,0,0,0,5,64,0,21,0,0,1,80,84,0,0,0,0,0,
HomineLudens 0:a92a22490aaa 39 0,0,5,64,0,0,21,0,21,0,0,0,0,0,0,0,1,80,0,0,21,0,85,64,1,84,0,0,0,0,0,0,0,5,64,0,21,64,0,1,64,84,0,0,0,0,0,
HomineLudens 0:a92a22490aaa 40 0,0,5,64,0,0,21,0,21,0,0,0,0,0,0,0,1,80,0,0,21,0,21,80,1,84,0,0,0,0,0,0,0,5,64,0,21,64,0,1,64,85,0,0,0,0,0,
HomineLudens 0:a92a22490aaa 41 0,0,5,64,0,0,21,0,21,64,0,5,0,0,0,0,1,80,0,0,21,0,21,84,0,85,0,0,16,0,0,0,0,5,64,0,21,80,0,5,0,85,64,0,0,0,0,
HomineLudens 0:a92a22490aaa 42 0,0,5,65,0,0,21,0,21,80,0,85,0,0,0,0,1,80,64,0,21,64,85,85,0,85,64,1,80,0,0,0,0,5,65,0,5,85,64,20,0,21,80,0,0,0,0,
HomineLudens 0:a92a22490aaa 43 0,0,5,85,0,0,21,84,5,85,85,84,0,0,0,0,1,85,64,0,21,85,81,85,64,85,85,85,80,0,0,0,0,5,85,0,1,85,85,80,0,21,85,85,64,0,0,
HomineLudens 0:a92a22490aaa 44 0,0,5,84,0,0,21,80,1,85,85,80,0,0,0,0,1,85,0,0,5,85,0,85,0,21,85,85,0,0,0,0,0,5,84,0,0,85,85,64,0,1,85,85,0,0,0,
HomineLudens 0:a92a22490aaa 45 0,0,1,80,0,0,21,64,0,21,85,0,0,0,0,0,0,84,0,0,1,80,0,16,0,1,85,80,0,0,0,0,0,1,80,0,0,5,84,0,0,0,85,80,0,0,0,
HomineLudens 0:a92a22490aaa 46 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,
HomineLudens 0:a92a22490aaa 47 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,
HomineLudens 0:a92a22490aaa 48 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,
HomineLudens 0:a92a22490aaa 49 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,
HomineLudens 0:a92a22490aaa 50 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,
HomineLudens 0:a92a22490aaa 51 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,
HomineLudens 0:a92a22490aaa 52 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,
HomineLudens 0:a92a22490aaa 53 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,
HomineLudens 0:a92a22490aaa 54 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,
HomineLudens 0:a92a22490aaa 55 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,
HomineLudens 0:a92a22490aaa 56 };
HomineLudens 0:a92a22490aaa 57
HomineLudens 0:a92a22490aaa 58
HomineLudens 0:a92a22490aaa 59 const uint8_t AI_logo[] = {
HomineLudens 0:a92a22490aaa 60 20,14,
HomineLudens 0:a92a22490aaa 61 0,0,0,0,0,
HomineLudens 0:a92a22490aaa 62 0,85,85,85,0,
HomineLudens 0:a92a22490aaa 63 1,85,85,85,64,
HomineLudens 0:a92a22490aaa 64 1,0,0,0,64,
HomineLudens 0:a92a22490aaa 65 1,0,0,0,64,
HomineLudens 0:a92a22490aaa 66 1,1,65,64,64,
HomineLudens 0:a92a22490aaa 67 1,1,65,64,64,
HomineLudens 0:a92a22490aaa 68 1,0,0,0,64,
HomineLudens 0:a92a22490aaa 69 1,0,0,0,64,
HomineLudens 0:a92a22490aaa 70 1,0,85,0,64,
HomineLudens 0:a92a22490aaa 71 1,0,20,0,64,
HomineLudens 0:a92a22490aaa 72 1,0,0,0,64,
HomineLudens 0:a92a22490aaa 73 1,0,0,0,64,
HomineLudens 0:a92a22490aaa 74 1,85,85,85,64,
HomineLudens 0:a92a22490aaa 75 };
HomineLudens 0:a92a22490aaa 76
HomineLudens 0:a92a22490aaa 77
HomineLudens 0:a92a22490aaa 78 const uint8_t P_logo[] = {
HomineLudens 0:a92a22490aaa 79 20,14,
HomineLudens 0:a92a22490aaa 80 0,0,85,0,0,
HomineLudens 0:a92a22490aaa 81 0,1,85,64,0,
HomineLudens 0:a92a22490aaa 82 0,1,85,64,0,
HomineLudens 0:a92a22490aaa 83 0,1,20,64,0,
HomineLudens 0:a92a22490aaa 84 0,5,85,80,0,
HomineLudens 0:a92a22490aaa 85 0,5,85,80,0,
HomineLudens 0:a92a22490aaa 86 0,1,20,64,0,
HomineLudens 0:a92a22490aaa 87 0,1,65,64,0,
HomineLudens 0:a92a22490aaa 88 0,0,85,0,0,
HomineLudens 0:a92a22490aaa 89 0,0,20,0,0,
HomineLudens 0:a92a22490aaa 90 0,21,85,84,0,
HomineLudens 0:a92a22490aaa 91 0,85,65,85,0,
HomineLudens 0:a92a22490aaa 92 0,85,85,85,0,
HomineLudens 0:a92a22490aaa 93 0,85,65,85,0,
HomineLudens 0:a92a22490aaa 94 };
HomineLudens 0:a92a22490aaa 95
HomineLudens 0:a92a22490aaa 96
HomineLudens 0:a92a22490aaa 97 Pokitto::Core game;
HomineLudens 0:a92a22490aaa 98 Pokitto::Display disp;
HomineLudens 0:a92a22490aaa 99 Pokitto::Sound snd;
HomineLudens 0:a92a22490aaa 100 Pokitto::Buttons btn;
HomineLudens 0:a92a22490aaa 101
HomineLudens 0:a92a22490aaa 102 typedef enum GameStates {
HomineLudens 0:a92a22490aaa 103 Menu=0,
HomineLudens 0:a92a22490aaa 104 InitGame,
HomineLudens 0:a92a22490aaa 105 Move,
HomineLudens 0:a92a22490aaa 106 Check,
HomineLudens 0:a92a22490aaa 107 Winner,
HomineLudens 0:a92a22490aaa 108 Drawn,
HomineLudens 0:a92a22490aaa 109 Credits
HomineLudens 0:a92a22490aaa 110 } GameStates;
HomineLudens 0:a92a22490aaa 111
HomineLudens 0:a92a22490aaa 112 typedef enum Symbol {
HomineLudens 0:a92a22490aaa 113 None=0,
HomineLudens 0:a92a22490aaa 114 Cross,
HomineLudens 0:a92a22490aaa 115 Circle,
HomineLudens 0:a92a22490aaa 116 Triangle,
HomineLudens 0:a92a22490aaa 117 Diamond,
HomineLudens 0:a92a22490aaa 118 } Symbol;
HomineLudens 0:a92a22490aaa 119
HomineLudens 0:a92a22490aaa 120 typedef struct {
HomineLudens 0:a92a22490aaa 121 short x;
HomineLudens 0:a92a22490aaa 122 short y;
HomineLudens 0:a92a22490aaa 123 } Point;
HomineLudens 0:a92a22490aaa 124
HomineLudens 0:a92a22490aaa 125 typedef struct {
HomineLudens 0:a92a22490aaa 126 bool winner;
HomineLudens 0:a92a22490aaa 127 Point from;
HomineLudens 0:a92a22490aaa 128 Point to;
HomineLudens 0:a92a22490aaa 129 Symbol symb;
HomineLudens 0:a92a22490aaa 130 short time;
HomineLudens 0:a92a22490aaa 131 } WinnerLine;
HomineLudens 0:a92a22490aaa 132
HomineLudens 0:a92a22490aaa 133 typedef struct {
HomineLudens 0:a92a22490aaa 134 Symbol symb;
HomineLudens 0:a92a22490aaa 135 short x;
HomineLudens 0:a92a22490aaa 136 short y;
HomineLudens 0:a92a22490aaa 137 short diameter;
HomineLudens 0:a92a22490aaa 138 short time;
HomineLudens 0:a92a22490aaa 139 float angle;
HomineLudens 0:a92a22490aaa 140 } Sign;
HomineLudens 0:a92a22490aaa 141
HomineLudens 0:a92a22490aaa 142 typedef struct Player {
HomineLudens 0:a92a22490aaa 143 bool AI;
HomineLudens 0:a92a22490aaa 144 Symbol symb;
HomineLudens 0:a92a22490aaa 145 } Player;
HomineLudens 0:a92a22490aaa 146
HomineLudens 0:a92a22490aaa 147 typedef struct MenuItem {
HomineLudens 0:a92a22490aaa 148 char * description;
HomineLudens 0:a92a22490aaa 149 int minValue;
HomineLudens 0:a92a22490aaa 150 int maxValue;
HomineLudens 0:a92a22490aaa 151 int value;
HomineLudens 0:a92a22490aaa 152 bool asBool;
HomineLudens 0:a92a22490aaa 153 } MenuItem;
HomineLudens 0:a92a22490aaa 154
HomineLudens 0:a92a22490aaa 155
HomineLudens 0:a92a22490aaa 156 MenuItem mainMenu[MAX_MENU_SETTINGS];
HomineLudens 0:a92a22490aaa 157 char menuIndex=0;
HomineLudens 0:a92a22490aaa 158
HomineLudens 0:a92a22490aaa 159 char setBoardSize=3;
HomineLudens 0:a92a22490aaa 160 char setSigns2Win=3;
HomineLudens 0:a92a22490aaa 161 char setNumPlayers=2;
HomineLudens 0:a92a22490aaa 162
HomineLudens 0:a92a22490aaa 163 Sign board[MAX_GRID_SIZE][MAX_GRID_SIZE];
HomineLudens 0:a92a22490aaa 164 Point cursor;
HomineLudens 0:a92a22490aaa 165
HomineLudens 0:a92a22490aaa 166 Player players[MAX_PLAYERS];
HomineLudens 0:a92a22490aaa 167 char playerTurn=0;
HomineLudens 0:a92a22490aaa 168 WinnerLine winnerLine;
HomineLudens 0:a92a22490aaa 169 GameStates gameState;
HomineLudens 0:a92a22490aaa 170 Point boardPosition = {.x=5,.y=5};
HomineLudens 0:a92a22490aaa 171
HomineLudens 0:a92a22490aaa 172 Sign scoreList[14];
HomineLudens 0:a92a22490aaa 173 char scoreListIndx=0;
HomineLudens 0:a92a22490aaa 174
HomineLudens 0:a92a22490aaa 175 uint32_t timer;
HomineLudens 0:a92a22490aaa 176
HomineLudens 0:a92a22490aaa 177
HomineLudens 0:a92a22490aaa 178 int clip(int n, int lower, int upper)
HomineLudens 0:a92a22490aaa 179 {
HomineLudens 0:a92a22490aaa 180 if (n<lower) return lower;
HomineLudens 0:a92a22490aaa 181 if (n>upper) return upper;
HomineLudens 0:a92a22490aaa 182 return n;
HomineLudens 0:a92a22490aaa 183 }
HomineLudens 0:a92a22490aaa 184
HomineLudens 0:a92a22490aaa 185 template <typename T>
HomineLudens 0:a92a22490aaa 186 T lerp(T a, T b, T t)
HomineLudens 0:a92a22490aaa 187 {
HomineLudens 0:a92a22490aaa 188 return a + (b - a) * cos(PI2*t/100.0);
HomineLudens 0:a92a22490aaa 189 }
HomineLudens 0:a92a22490aaa 190
HomineLudens 0:a92a22490aaa 191 void initMenu()
HomineLudens 0:a92a22490aaa 192 {
HomineLudens 0:a92a22490aaa 193 MenuItem menuSize;
HomineLudens 0:a92a22490aaa 194 menuSize.description="Board Size (NxN)";
HomineLudens 0:a92a22490aaa 195 menuSize.minValue=2;
HomineLudens 0:a92a22490aaa 196 menuSize.maxValue=5;
HomineLudens 0:a92a22490aaa 197 menuSize.value=3;
HomineLudens 0:a92a22490aaa 198 menuSize.asBool=false;
HomineLudens 0:a92a22490aaa 199 mainMenu[0]=menuSize;
HomineLudens 0:a92a22490aaa 200
HomineLudens 0:a92a22490aaa 201 MenuItem menuSigns2Win;
HomineLudens 0:a92a22490aaa 202 menuSigns2Win.description="Signs to win";
HomineLudens 0:a92a22490aaa 203 menuSigns2Win.minValue=2;
HomineLudens 0:a92a22490aaa 204 menuSigns2Win.maxValue=5;
HomineLudens 0:a92a22490aaa 205 menuSigns2Win.value=3;
HomineLudens 0:a92a22490aaa 206 menuSigns2Win.asBool=false;
HomineLudens 0:a92a22490aaa 207 mainMenu[1]=menuSigns2Win;
HomineLudens 0:a92a22490aaa 208
HomineLudens 0:a92a22490aaa 209 MenuItem menuNumPlayers;
HomineLudens 0:a92a22490aaa 210 menuNumPlayers.description="Number of players";
HomineLudens 0:a92a22490aaa 211 menuNumPlayers.minValue=2;
HomineLudens 0:a92a22490aaa 212 menuNumPlayers.maxValue=4;
HomineLudens 0:a92a22490aaa 213 menuNumPlayers.value=2;
HomineLudens 0:a92a22490aaa 214 menuNumPlayers.asBool=false;
HomineLudens 0:a92a22490aaa 215 mainMenu[2]=menuNumPlayers;
HomineLudens 0:a92a22490aaa 216
HomineLudens 0:a92a22490aaa 217 MenuItem P1Settings;
HomineLudens 0:a92a22490aaa 218 P1Settings.description="Player 1";
HomineLudens 0:a92a22490aaa 219 P1Settings.minValue=0;
HomineLudens 0:a92a22490aaa 220 P1Settings.maxValue=1;
HomineLudens 0:a92a22490aaa 221 P1Settings.value=0;
HomineLudens 0:a92a22490aaa 222 P1Settings.asBool=true;
HomineLudens 0:a92a22490aaa 223 mainMenu[3]=P1Settings;
HomineLudens 0:a92a22490aaa 224
HomineLudens 0:a92a22490aaa 225 MenuItem P2Settings;
HomineLudens 0:a92a22490aaa 226 P2Settings.description="Player 2";
HomineLudens 0:a92a22490aaa 227 P2Settings.minValue=0;
HomineLudens 0:a92a22490aaa 228 P2Settings.maxValue=1;
HomineLudens 0:a92a22490aaa 229 P2Settings.value=1;
HomineLudens 0:a92a22490aaa 230 P2Settings.asBool=true;
HomineLudens 0:a92a22490aaa 231 mainMenu[4]=P2Settings;
HomineLudens 0:a92a22490aaa 232
HomineLudens 0:a92a22490aaa 233 MenuItem P3Settings;
HomineLudens 0:a92a22490aaa 234 P3Settings.description="Player 3";
HomineLudens 0:a92a22490aaa 235 P3Settings.minValue=0;
HomineLudens 0:a92a22490aaa 236 P3Settings.maxValue=1;
HomineLudens 0:a92a22490aaa 237 P3Settings.value=1;
HomineLudens 0:a92a22490aaa 238 P3Settings.asBool=true;
HomineLudens 0:a92a22490aaa 239 mainMenu[5]=P3Settings;
HomineLudens 0:a92a22490aaa 240
HomineLudens 0:a92a22490aaa 241 MenuItem P4Settings;
HomineLudens 0:a92a22490aaa 242 P4Settings.description="Player 4";
HomineLudens 0:a92a22490aaa 243 P4Settings.minValue=0;
HomineLudens 0:a92a22490aaa 244 P4Settings.maxValue=1;
HomineLudens 0:a92a22490aaa 245 P4Settings.value=1;
HomineLudens 0:a92a22490aaa 246 P4Settings.asBool=true;
HomineLudens 0:a92a22490aaa 247 mainMenu[6]=P4Settings;
HomineLudens 0:a92a22490aaa 248
HomineLudens 0:a92a22490aaa 249 }
HomineLudens 0:a92a22490aaa 250
HomineLudens 0:a92a22490aaa 251 void drawMenuItem(short x,short y,MenuItem item)
HomineLudens 0:a92a22490aaa 252 {
HomineLudens 0:a92a22490aaa 253 disp.color=1;
HomineLudens 0:a92a22490aaa 254 disp.print(x,y,item.description);
HomineLudens 0:a92a22490aaa 255
HomineLudens 0:a92a22490aaa 256
HomineLudens 0:a92a22490aaa 257 if(item.asBool) {
HomineLudens 0:a92a22490aaa 258 if (item.value==1) {
HomineLudens 0:a92a22490aaa 259 disp.drawBitmap(x+112,y-(AI_logo[1]/2)+3,AI_logo);
HomineLudens 0:a92a22490aaa 260 } else {
HomineLudens 0:a92a22490aaa 261 disp.drawBitmap(x+112,y-(AI_logo[1]/2)+3,P_logo);
HomineLudens 0:a92a22490aaa 262 }
HomineLudens 0:a92a22490aaa 263
HomineLudens 0:a92a22490aaa 264 } else {
HomineLudens 0:a92a22490aaa 265 disp.color=2;
HomineLudens 0:a92a22490aaa 266 disp.print(x+120,y,(int)item.value);
HomineLudens 0:a92a22490aaa 267 }
HomineLudens 0:a92a22490aaa 268 }
HomineLudens 0:a92a22490aaa 269
HomineLudens 0:a92a22490aaa 270
HomineLudens 0:a92a22490aaa 271 void drawPolygon (short xc, short yc, short r, short n,float a)
HomineLudens 0:a92a22490aaa 272 {
HomineLudens 0:a92a22490aaa 273 short lastx;
HomineLudens 0:a92a22490aaa 274 short lasty;
HomineLudens 0:a92a22490aaa 275 a-=PI2;
HomineLudens 0:a92a22490aaa 276 short x = (int)((float)xc + (float)r * cos(a));
HomineLudens 0:a92a22490aaa 277 short y = (int) ((float)yc + (float)r * sin(a));
HomineLudens 0:a92a22490aaa 278
HomineLudens 0:a92a22490aaa 279 for (int i = 0; i < n; i++) {
HomineLudens 0:a92a22490aaa 280 lastx = x;
HomineLudens 0:a92a22490aaa 281 lasty = y;
HomineLudens 0:a92a22490aaa 282 a = a + (2 * PI / n);
HomineLudens 0:a92a22490aaa 283 x = (int) ((float)xc + (float)r * cos(a));
HomineLudens 0:a92a22490aaa 284 y = (int) ((float)yc + (float)r * sin(a));
HomineLudens 0:a92a22490aaa 285 disp.drawLine(lastx, lasty, x, y);
HomineLudens 0:a92a22490aaa 286 }
HomineLudens 0:a92a22490aaa 287 }
HomineLudens 0:a92a22490aaa 288
HomineLudens 0:a92a22490aaa 289 void drawCross(short xc, short yc, short r, short n,float a)
HomineLudens 0:a92a22490aaa 290 {
HomineLudens 0:a92a22490aaa 291 short x;
HomineLudens 0:a92a22490aaa 292 short y;
HomineLudens 0:a92a22490aaa 293 a-=PI/4;
HomineLudens 0:a92a22490aaa 294 for (int i = 0; i < n; i++) {
HomineLudens 0:a92a22490aaa 295 x = (int) ((float)xc + (float)r * cos(a));
HomineLudens 0:a92a22490aaa 296 y = (int) ((float)yc + (float)r * sin(a));
HomineLudens 0:a92a22490aaa 297 a = a + (2 * PI / n);
HomineLudens 0:a92a22490aaa 298 disp.drawLine(xc, yc, x, y);
HomineLudens 0:a92a22490aaa 299 }
HomineLudens 0:a92a22490aaa 300 }
HomineLudens 0:a92a22490aaa 301
HomineLudens 0:a92a22490aaa 302 void drawSign(Sign symb)
HomineLudens 0:a92a22490aaa 303 {
HomineLudens 0:a92a22490aaa 304 if (symb.symb==Cross) {
HomineLudens 0:a92a22490aaa 305 disp.color=1;
HomineLudens 0:a92a22490aaa 306 drawCross(symb.x,symb.y,symb.diameter/2,4,symb.angle);
HomineLudens 0:a92a22490aaa 307 }
HomineLudens 0:a92a22490aaa 308
HomineLudens 0:a92a22490aaa 309 if (symb.symb==Circle) {
HomineLudens 0:a92a22490aaa 310 disp.color=2;
HomineLudens 0:a92a22490aaa 311 disp.drawCircle(symb.x,symb.y,symb.diameter/2-sin(symb.angle)*symb.diameter/5.0);// symb.diameter/2 + 2*PI/symb.angle );
HomineLudens 0:a92a22490aaa 312 }
HomineLudens 0:a92a22490aaa 313
HomineLudens 0:a92a22490aaa 314 if (symb.symb==Triangle) {
HomineLudens 0:a92a22490aaa 315 disp.color=3;
HomineLudens 0:a92a22490aaa 316 drawPolygon(symb.x,symb.y,symb.diameter/2,3,symb.angle);
HomineLudens 0:a92a22490aaa 317 }
HomineLudens 0:a92a22490aaa 318
HomineLudens 0:a92a22490aaa 319 if (symb.symb==Diamond) {
HomineLudens 0:a92a22490aaa 320 disp.color=1;
HomineLudens 0:a92a22490aaa 321 drawPolygon(symb.x,symb.y,symb.diameter/2,4,symb.angle);
HomineLudens 0:a92a22490aaa 322 }
HomineLudens 0:a92a22490aaa 323 }
HomineLudens 0:a92a22490aaa 324
HomineLudens 0:a92a22490aaa 325 void drawRectangle(double x1,double y1,double x2,double y2,double width,double offsetAngle)
HomineLudens 0:a92a22490aaa 326 {
HomineLudens 0:a92a22490aaa 327 Point pp[4];
HomineLudens 0:a92a22490aaa 328 //Base angle
HomineLudens 0:a92a22490aaa 329 double angle=-atan2(y1-y2,x1-x2)+PI2;
HomineLudens 0:a92a22490aaa 330
HomineLudens 0:a92a22490aaa 331 double xc=(x1+x2)/2;
HomineLudens 0:a92a22490aaa 332 double yc=(y1+y2)/2;
HomineLudens 0:a92a22490aaa 333 double d2=sqrt(((x1-x2)*(x1-x2))+((y1-y2)*(y1-y2)))/2;
HomineLudens 0:a92a22490aaa 334
HomineLudens 0:a92a22490aaa 335 x1=xc+d2*sin(angle+offsetAngle);
HomineLudens 0:a92a22490aaa 336 y1=yc+d2*cos(angle+offsetAngle);
HomineLudens 0:a92a22490aaa 337 x2=xc+d2*sin(angle+offsetAngle-PI);
HomineLudens 0:a92a22490aaa 338 y2=yc+d2*cos(angle+offsetAngle-PI);
HomineLudens 0:a92a22490aaa 339
HomineLudens 0:a92a22490aaa 340 //Recalculate angle after offset angle is applied
HomineLudens 0:a92a22490aaa 341 angle=-atan2(y1-y2,x1-x2);
HomineLudens 0:a92a22490aaa 342
HomineLudens 0:a92a22490aaa 343 pp[0].x=x1+width*sin(angle+PI4);
HomineLudens 0:a92a22490aaa 344 pp[0].y=y1+width*cos(angle+PI4);
HomineLudens 0:a92a22490aaa 345 pp[1].x=x2+width*sin(angle-PI4);
HomineLudens 0:a92a22490aaa 346 pp[1].y=y2+width*cos(angle-PI4);
HomineLudens 0:a92a22490aaa 347
HomineLudens 0:a92a22490aaa 348 pp[2].x=x2+width*sin(angle-PI3_4);
HomineLudens 0:a92a22490aaa 349 pp[2].y=y2+width*cos(angle-PI3_4);
HomineLudens 0:a92a22490aaa 350 pp[3].x=x1+width*sin(angle+PI3_4);
HomineLudens 0:a92a22490aaa 351 pp[3].y=y1+width*cos(angle+PI3_4);
HomineLudens 0:a92a22490aaa 352
HomineLudens 0:a92a22490aaa 353 for(short i=0; i<4; i++) {
HomineLudens 0:a92a22490aaa 354 disp.drawLine(pp[i].x,pp[i].y,pp[(i+1)%4].x,pp[(i+1)%4].y);
HomineLudens 0:a92a22490aaa 355 //disp.drawLine(xc,yc,pp[i].x,pp[i].y);
HomineLudens 0:a92a22490aaa 356 }
HomineLudens 0:a92a22490aaa 357 //disp.drawLine(x1,y1,x2,y2);
HomineLudens 0:a92a22490aaa 358
HomineLudens 0:a92a22490aaa 359 }
HomineLudens 0:a92a22490aaa 360
HomineLudens 0:a92a22490aaa 361 void drawWinningLine(short xo,short yo,WinnerLine win)
HomineLudens 0:a92a22490aaa 362 {
HomineLudens 0:a92a22490aaa 363 short x1=xo+win.from.x * CELL_SIZE + CELL_SIZE/2;
HomineLudens 0:a92a22490aaa 364 short y1=yo+win.from.y * CELL_SIZE+ CELL_SIZE/2;
HomineLudens 0:a92a22490aaa 365 short x2=xo+win.to.x * CELL_SIZE+ CELL_SIZE/2;
HomineLudens 0:a92a22490aaa 366 short y2=yo+win.to.y * CELL_SIZE+ CELL_SIZE/2;
HomineLudens 0:a92a22490aaa 367 double a=lerp(0.0,2.0*PI,(double)win.time);
HomineLudens 0:a92a22490aaa 368
HomineLudens 0:a92a22490aaa 369 disp.color=3;
HomineLudens 0:a92a22490aaa 370 //drawRectangle(x1,y1,x2,y2,SIGN_SIZE,a);
HomineLudens 0:a92a22490aaa 371 drawRectangle(x1,y1,x2,y2,SIGN_SIZE-2,a);
HomineLudens 0:a92a22490aaa 372 }
HomineLudens 0:a92a22490aaa 373
HomineLudens 0:a92a22490aaa 374 void drawMenu()
HomineLudens 0:a92a22490aaa 375 {
HomineLudens 0:a92a22490aaa 376 short xo;
HomineLudens 0:a92a22490aaa 377 short yo;
HomineLudens 0:a92a22490aaa 378
HomineLudens 0:a92a22490aaa 379 xo=(disp.width-logo[0])/2;
HomineLudens 0:a92a22490aaa 380
HomineLudens 0:a92a22490aaa 381 //draw logo
HomineLudens 0:a92a22490aaa 382 disp.drawBitmap(xo,0,logo);
HomineLudens 0:a92a22490aaa 383
HomineLudens 0:a92a22490aaa 384 yo=logo[1];//logo height
HomineLudens 0:a92a22490aaa 385 xo=40;
HomineLudens 0:a92a22490aaa 386
HomineLudens 0:a92a22490aaa 387 //draw cursor
HomineLudens 0:a92a22490aaa 388 disp.color=3;
HomineLudens 0:a92a22490aaa 389 disp.print(xo-10,yo+(menuIndex*16),">");
HomineLudens 0:a92a22490aaa 390 //draw menu items
HomineLudens 0:a92a22490aaa 391 for (char m=0; m<sizeof(mainMenu)/sizeof(MenuItem); m++) {
HomineLudens 0:a92a22490aaa 392 drawMenuItem(xo,yo,mainMenu[m]);
HomineLudens 0:a92a22490aaa 393 yo+=16;
HomineLudens 0:a92a22490aaa 394 }
HomineLudens 0:a92a22490aaa 395
HomineLudens 0:a92a22490aaa 396 //draw instructions
HomineLudens 0:a92a22490aaa 397 disp.color=3;
HomineLudens 0:a92a22490aaa 398 disp.print(25,disp.height-30," Up/Down select menu");
HomineLudens 0:a92a22490aaa 399 disp.print(25,disp.height-20," Left/Right change value");
HomineLudens 0:a92a22490aaa 400 disp.print(25,disp.height-10,"A=Start Game B=Shuffle C=Menu");
HomineLudens 0:a92a22490aaa 401 }
HomineLudens 0:a92a22490aaa 402
HomineLudens 0:a92a22490aaa 403 void drawGameInfo()
HomineLudens 0:a92a22490aaa 404 {
HomineLudens 0:a92a22490aaa 405 disp.print((int)setNumPlayers);
HomineLudens 0:a92a22490aaa 406 disp.print("P [");
HomineLudens 0:a92a22490aaa 407 disp.print((int)setBoardSize);
HomineLudens 0:a92a22490aaa 408 disp.print("x");
HomineLudens 0:a92a22490aaa 409 disp.print((int)setBoardSize);
HomineLudens 0:a92a22490aaa 410 disp.print("] ");
HomineLudens 0:a92a22490aaa 411 disp.print((int)setSigns2Win);
HomineLudens 0:a92a22490aaa 412 disp.print(" to win");
HomineLudens 0:a92a22490aaa 413 }
HomineLudens 0:a92a22490aaa 414
HomineLudens 0:a92a22490aaa 415 void drawBoard(short xo,short yo)
HomineLudens 0:a92a22490aaa 416 {
HomineLudens 0:a92a22490aaa 417 short xc;
HomineLudens 0:a92a22490aaa 418 short yc;
HomineLudens 0:a92a22490aaa 419
HomineLudens 0:a92a22490aaa 420 drawGameInfo();
HomineLudens 0:a92a22490aaa 421
HomineLudens 0:a92a22490aaa 422 //Vertical lines
HomineLudens 0:a92a22490aaa 423 disp.color=1;
HomineLudens 0:a92a22490aaa 424 for (char x=1; x<setBoardSize; x++) {
HomineLudens 0:a92a22490aaa 425 disp.drawLine(xo+(CELL_SIZE*x),yo,xo+(CELL_SIZE*x),yo+(CELL_SIZE*(setBoardSize)));
HomineLudens 0:a92a22490aaa 426 }
HomineLudens 0:a92a22490aaa 427 //Horizontal lines
HomineLudens 0:a92a22490aaa 428 for (char y=1; y<setBoardSize; y++) {
HomineLudens 0:a92a22490aaa 429 disp.drawLine(xo,yo+(CELL_SIZE*y),xo+CELL_SIZE*(setBoardSize),yo+(CELL_SIZE*y));
HomineLudens 0:a92a22490aaa 430 }
HomineLudens 0:a92a22490aaa 431
HomineLudens 0:a92a22490aaa 432 //Draw Cell
HomineLudens 0:a92a22490aaa 433 for (char x=0; x<setBoardSize; x++) {
HomineLudens 0:a92a22490aaa 434 for (char y=0; y<setBoardSize; y++) {
HomineLudens 0:a92a22490aaa 435 //Update symbols time for animations
HomineLudens 0:a92a22490aaa 436 if ( board[x][y].time<100) board[x][y].time+=5;
HomineLudens 0:a92a22490aaa 437 board[x][y].angle=lerp((float)0,(float)2*PI,(float)board[x][y].time);
HomineLudens 0:a92a22490aaa 438
HomineLudens 0:a92a22490aaa 439 //Calculate center of the cell
HomineLudens 0:a92a22490aaa 440 xc=xo+(x*CELL_SIZE)+(CELL_SIZE/2);
HomineLudens 0:a92a22490aaa 441 yc=yo+(y*CELL_SIZE)+(CELL_SIZE/2);
HomineLudens 0:a92a22490aaa 442 board[x][y].x=xc;
HomineLudens 0:a92a22490aaa 443 board[x][y].y=yc;
HomineLudens 0:a92a22490aaa 444
HomineLudens 0:a92a22490aaa 445 //Draw cursor
HomineLudens 0:a92a22490aaa 446 if (cursor.x==x && cursor.y==y) {
HomineLudens 0:a92a22490aaa 447 disp.color=3;
HomineLudens 0:a92a22490aaa 448 drawPolygon(xc,yc,CURSOR_SIZE/2,4,-PI/4);
HomineLudens 0:a92a22490aaa 449 }
HomineLudens 0:a92a22490aaa 450
HomineLudens 0:a92a22490aaa 451 //Draw symbol of the board
HomineLudens 0:a92a22490aaa 452 drawSign(board[x][y]);
HomineLudens 0:a92a22490aaa 453 }
HomineLudens 0:a92a22490aaa 454 }
HomineLudens 0:a92a22490aaa 455
HomineLudens 0:a92a22490aaa 456 //Draw player symbol at top/right corner
HomineLudens 0:a92a22490aaa 457 Sign playerSign;
HomineLudens 0:a92a22490aaa 458 playerSign.symb=players[playerTurn].symb;
HomineLudens 0:a92a22490aaa 459 playerSign.x=disp.width-(SIGN_SIZE/2);
HomineLudens 0:a92a22490aaa 460 playerSign.y=SIGN_SIZE/2;
HomineLudens 1:cdc038225cf5 461 playerSign.diameter=SIGN_SIZE;
HomineLudens 0:a92a22490aaa 462 drawSign(playerSign);
HomineLudens 0:a92a22490aaa 463
HomineLudens 0:a92a22490aaa 464 //draw winner list
HomineLudens 0:a92a22490aaa 465 disp.drawRect(disp.width-SIGN_SIZE,0,SIGN_SIZE-1,SIGN_SIZE);
HomineLudens 0:a92a22490aaa 466 disp.drawRect(disp.width-SIGN_SIZE,0,SIGN_SIZE-1,disp.height-1);
HomineLudens 0:a92a22490aaa 467 for (int i=0; i<sizeof(scoreList)/sizeof(Sign); i++) {
HomineLudens 0:a92a22490aaa 468 drawSign(scoreList[i]);
HomineLudens 0:a92a22490aaa 469 }
HomineLudens 0:a92a22490aaa 470 }
HomineLudens 0:a92a22490aaa 471
HomineLudens 0:a92a22490aaa 472 void initGame()
HomineLudens 0:a92a22490aaa 473 {
HomineLudens 0:a92a22490aaa 474 //Center board
HomineLudens 0:a92a22490aaa 475 boardPosition.x=((disp.width-20)-(setBoardSize*CELL_SIZE))/2;
HomineLudens 0:a92a22490aaa 476 boardPosition.y=6+((disp.height-6)-(setBoardSize*CELL_SIZE))/2;
HomineLudens 0:a92a22490aaa 477
HomineLudens 0:a92a22490aaa 478 //Initialize cursor position
HomineLudens 0:a92a22490aaa 479 cursor.x=(int)(setBoardSize/2);
HomineLudens 0:a92a22490aaa 480 cursor.y=(int)(setBoardSize/2);
HomineLudens 0:a92a22490aaa 481
HomineLudens 0:a92a22490aaa 482 //reset winnerLine
HomineLudens 0:a92a22490aaa 483 winnerLine.winner=false;
HomineLudens 0:a92a22490aaa 484
HomineLudens 0:a92a22490aaa 485 //Clear board
HomineLudens 0:a92a22490aaa 486 for (char x=0; x<setBoardSize; x++) {
HomineLudens 0:a92a22490aaa 487 for (char y=0; y<setBoardSize; y++) {
HomineLudens 0:a92a22490aaa 488 board[x][y].symb=None;
HomineLudens 1:cdc038225cf5 489 board[x][y].diameter=SIGN_SIZE;
HomineLudens 0:a92a22490aaa 490 }
HomineLudens 0:a92a22490aaa 491 }
HomineLudens 0:a92a22490aaa 492
HomineLudens 0:a92a22490aaa 493 //Begin game
HomineLudens 0:a92a22490aaa 494 gameState=Move;
HomineLudens 0:a92a22490aaa 495 }
HomineLudens 0:a92a22490aaa 496
HomineLudens 0:a92a22490aaa 497 void updateMenu()
HomineLudens 0:a92a22490aaa 498 {
HomineLudens 0:a92a22490aaa 499 //Scroll the menu settings
HomineLudens 0:a92a22490aaa 500 if (btn.pressed(BTN_DOWN)) menuIndex++;
HomineLudens 0:a92a22490aaa 501 if (btn.pressed(BTN_UP)) menuIndex--;
HomineLudens 0:a92a22490aaa 502 menuIndex=clip(menuIndex,0,MAX_MENU_SETTINGS-1);
HomineLudens 0:a92a22490aaa 503
HomineLudens 0:a92a22490aaa 504 //Change menu values
HomineLudens 0:a92a22490aaa 505 if (btn.pressed(BTN_RIGHT))mainMenu[menuIndex].value++;
HomineLudens 0:a92a22490aaa 506 if (btn.pressed(BTN_LEFT))mainMenu[menuIndex].value--;
HomineLudens 0:a92a22490aaa 507 mainMenu[menuIndex].value=clip(mainMenu[menuIndex].value,mainMenu[menuIndex].minValue,mainMenu[menuIndex].maxValue);
HomineLudens 0:a92a22490aaa 508
HomineLudens 0:a92a22490aaa 509 //Start game
HomineLudens 0:a92a22490aaa 510 if (btn.pressed(BTN_A)) {
HomineLudens 0:a92a22490aaa 511 setBoardSize=mainMenu[0].value;
HomineLudens 0:a92a22490aaa 512 setSigns2Win=mainMenu[1].value;
HomineLudens 0:a92a22490aaa 513 setNumPlayers=mainMenu[2].value;
HomineLudens 0:a92a22490aaa 514
HomineLudens 0:a92a22490aaa 515 //
HomineLudens 0:a92a22490aaa 516 players[0].symb=Cross;
HomineLudens 0:a92a22490aaa 517 players[0].AI=mainMenu[3].value==1;
HomineLudens 0:a92a22490aaa 518
HomineLudens 0:a92a22490aaa 519 players[1].symb=Circle;
HomineLudens 0:a92a22490aaa 520 players[1].AI=mainMenu[4].value==1;
HomineLudens 0:a92a22490aaa 521
HomineLudens 0:a92a22490aaa 522 players[2].symb=Triangle;
HomineLudens 0:a92a22490aaa 523 players[2].AI=mainMenu[5].value==1;
HomineLudens 0:a92a22490aaa 524
HomineLudens 0:a92a22490aaa 525 players[3].symb=Diamond;
HomineLudens 0:a92a22490aaa 526 players[3].AI=mainMenu[6].value==1;
HomineLudens 0:a92a22490aaa 527
HomineLudens 0:a92a22490aaa 528 gameState=InitGame;
HomineLudens 0:a92a22490aaa 529 }
HomineLudens 0:a92a22490aaa 530
HomineLudens 0:a92a22490aaa 531 //Randomize data
HomineLudens 0:a92a22490aaa 532 if(btn.pressed((BTN_B))) {
HomineLudens 0:a92a22490aaa 533 mainMenu[0].value=random(3,5); //board
HomineLudens 0:a92a22490aaa 534 mainMenu[1].value=random(2,mainMenu[0].value); //signs to win
HomineLudens 0:a92a22490aaa 535 mainMenu[2].value=random(2,4);//players
HomineLudens 0:a92a22490aaa 536
HomineLudens 0:a92a22490aaa 537 mainMenu[3].value=random(0,1);//P1 AI
HomineLudens 0:a92a22490aaa 538 mainMenu[4].value=random(0,1);//P2 AI
HomineLudens 0:a92a22490aaa 539 mainMenu[5].value=random(0,1);//P3 AI
HomineLudens 0:a92a22490aaa 540 mainMenu[6].value=random(0,1);//P4 AI
HomineLudens 0:a92a22490aaa 541 }
HomineLudens 0:a92a22490aaa 542 drawMenu();
HomineLudens 0:a92a22490aaa 543 }
HomineLudens 0:a92a22490aaa 544
HomineLudens 0:a92a22490aaa 545
HomineLudens 0:a92a22490aaa 546 bool isWinner(Sign originalBoard[MAX_GRID_SIZE][MAX_GRID_SIZE],Symbol symb,short xm=-1,short ym=-1)
HomineLudens 0:a92a22490aaa 547 {
HomineLudens 0:a92a22490aaa 548 short xc;
HomineLudens 0:a92a22490aaa 549 short yc;
HomineLudens 0:a92a22490aaa 550
HomineLudens 0:a92a22490aaa 551 //Copy board to test
HomineLudens 0:a92a22490aaa 552 Sign boardTest[setBoardSize][setBoardSize];
HomineLudens 0:a92a22490aaa 553 for (char x=0; x<setBoardSize; x++) {
HomineLudens 0:a92a22490aaa 554 for (char y=0; y<setBoardSize; y++) {
HomineLudens 0:a92a22490aaa 555 boardTest[x][y]=originalBoard[x][y];
HomineLudens 0:a92a22490aaa 556 }
HomineLudens 0:a92a22490aaa 557 }
HomineLudens 0:a92a22490aaa 558
HomineLudens 0:a92a22490aaa 559 //If a move is request
HomineLudens 0:a92a22490aaa 560 if(xm>-1 && ym>-1) {
HomineLudens 0:a92a22490aaa 561 //place the symbol, if we can
HomineLudens 0:a92a22490aaa 562 if(boardTest[xm][ym].symb==None) {
HomineLudens 0:a92a22490aaa 563 boardTest[xm][ym].symb=symb;
HomineLudens 0:a92a22490aaa 564 }
HomineLudens 0:a92a22490aaa 565 }
HomineLudens 0:a92a22490aaa 566
HomineLudens 0:a92a22490aaa 567 //NOW check all winning conditions
HomineLudens 0:a92a22490aaa 568 bool win;
HomineLudens 0:a92a22490aaa 569 winnerLine.time=0;
HomineLudens 0:a92a22490aaa 570 for (char x=0; x<setBoardSize; x++) {
HomineLudens 0:a92a22490aaa 571 for (char y=0; y<setBoardSize; y++) {
HomineLudens 0:a92a22490aaa 572 //horizontal win
HomineLudens 0:a92a22490aaa 573 win=true;
HomineLudens 0:a92a22490aaa 574 for (char c=0; c<setSigns2Win; c++ ) {
HomineLudens 0:a92a22490aaa 575 xc=c+x;
HomineLudens 0:a92a22490aaa 576 yc=y;
HomineLudens 0:a92a22490aaa 577 if(xc>=0 && xc<setBoardSize && yc>=0 && yc<setBoardSize)
HomineLudens 0:a92a22490aaa 578 win=win && boardTest[xc][yc].symb==symb;
HomineLudens 0:a92a22490aaa 579 else
HomineLudens 0:a92a22490aaa 580 win=false;
HomineLudens 0:a92a22490aaa 581 }
HomineLudens 0:a92a22490aaa 582
HomineLudens 0:a92a22490aaa 583 if(win) {
HomineLudens 0:a92a22490aaa 584 winnerLine.winner=true;
HomineLudens 0:a92a22490aaa 585 winnerLine.from.x=x;
HomineLudens 0:a92a22490aaa 586 winnerLine.from.y=y;
HomineLudens 0:a92a22490aaa 587 winnerLine.to.x=x+setSigns2Win-1;
HomineLudens 0:a92a22490aaa 588 winnerLine.to.y=y;
HomineLudens 0:a92a22490aaa 589 winnerLine.symb=symb;
HomineLudens 0:a92a22490aaa 590 return true;
HomineLudens 0:a92a22490aaa 591 }
HomineLudens 0:a92a22490aaa 592
HomineLudens 0:a92a22490aaa 593 //vertical win
HomineLudens 0:a92a22490aaa 594 win=true;
HomineLudens 0:a92a22490aaa 595 for (char c=0; c<setSigns2Win; c++ ) {
HomineLudens 0:a92a22490aaa 596 xc=x;
HomineLudens 0:a92a22490aaa 597 yc=c+y;
HomineLudens 0:a92a22490aaa 598 if(xc>=0 && xc<setBoardSize && yc>=0 && yc<setBoardSize)
HomineLudens 0:a92a22490aaa 599 win=win && boardTest[xc][yc].symb==symb;
HomineLudens 0:a92a22490aaa 600 else
HomineLudens 0:a92a22490aaa 601 win=false;
HomineLudens 0:a92a22490aaa 602 }
HomineLudens 0:a92a22490aaa 603
HomineLudens 0:a92a22490aaa 604 if(win) {
HomineLudens 0:a92a22490aaa 605 winnerLine.winner=true;
HomineLudens 0:a92a22490aaa 606 winnerLine.from.x=x;
HomineLudens 0:a92a22490aaa 607 winnerLine.from.y=y;
HomineLudens 0:a92a22490aaa 608 winnerLine.to.x=x;
HomineLudens 0:a92a22490aaa 609 winnerLine.to.y=y+setSigns2Win-1;
HomineLudens 0:a92a22490aaa 610 winnerLine.symb=symb;
HomineLudens 0:a92a22490aaa 611 return true;
HomineLudens 0:a92a22490aaa 612 }
HomineLudens 0:a92a22490aaa 613
HomineLudens 0:a92a22490aaa 614 //diagonal top/right win
HomineLudens 0:a92a22490aaa 615 win=true;
HomineLudens 0:a92a22490aaa 616 for (char c=0; c<setSigns2Win; c++ ) {
HomineLudens 0:a92a22490aaa 617 xc=c+x;
HomineLudens 0:a92a22490aaa 618 yc=c+y;
HomineLudens 0:a92a22490aaa 619 if(xc>=0 && xc<setBoardSize && yc>=0 && yc<setBoardSize)
HomineLudens 0:a92a22490aaa 620 win=win && boardTest[xc][yc].symb==symb;
HomineLudens 0:a92a22490aaa 621 else
HomineLudens 0:a92a22490aaa 622 win=false;
HomineLudens 0:a92a22490aaa 623 }
HomineLudens 0:a92a22490aaa 624
HomineLudens 0:a92a22490aaa 625 if(win) {
HomineLudens 0:a92a22490aaa 626 winnerLine.winner=true;
HomineLudens 0:a92a22490aaa 627 winnerLine.from.x=x;
HomineLudens 0:a92a22490aaa 628 winnerLine.from.y=y;
HomineLudens 0:a92a22490aaa 629 winnerLine.to.x=x+setSigns2Win-1;
HomineLudens 0:a92a22490aaa 630 winnerLine.to.y=y+setSigns2Win-1;
HomineLudens 0:a92a22490aaa 631 winnerLine.symb=symb;
HomineLudens 0:a92a22490aaa 632 return true;
HomineLudens 0:a92a22490aaa 633 }
HomineLudens 0:a92a22490aaa 634
HomineLudens 0:a92a22490aaa 635 //diagonal top/left win
HomineLudens 0:a92a22490aaa 636 win=true;
HomineLudens 0:a92a22490aaa 637 for (char c=0; c<setSigns2Win; c++ ) {
HomineLudens 0:a92a22490aaa 638 xc=-c+x;
HomineLudens 0:a92a22490aaa 639 yc=c+y;
HomineLudens 0:a92a22490aaa 640 if(xc>=0 && xc<setBoardSize && yc>=0 && yc<setBoardSize)
HomineLudens 0:a92a22490aaa 641 win=win && boardTest[xc][yc].symb==symb;
HomineLudens 0:a92a22490aaa 642 else
HomineLudens 0:a92a22490aaa 643 win=false;
HomineLudens 0:a92a22490aaa 644 }
HomineLudens 0:a92a22490aaa 645
HomineLudens 0:a92a22490aaa 646 if(win) {
HomineLudens 0:a92a22490aaa 647 winnerLine.winner=true;
HomineLudens 0:a92a22490aaa 648 winnerLine.from.x=x;
HomineLudens 0:a92a22490aaa 649 winnerLine.from.y=y;
HomineLudens 0:a92a22490aaa 650 winnerLine.to.x=x-setSigns2Win+1;
HomineLudens 0:a92a22490aaa 651 winnerLine.to.y=y+setSigns2Win-1;
HomineLudens 0:a92a22490aaa 652 winnerLine.symb=symb;
HomineLudens 0:a92a22490aaa 653 return true;
HomineLudens 0:a92a22490aaa 654 }
HomineLudens 0:a92a22490aaa 655 }
HomineLudens 0:a92a22490aaa 656 }
HomineLudens 0:a92a22490aaa 657
HomineLudens 0:a92a22490aaa 658 winnerLine.winner=false;
HomineLudens 0:a92a22490aaa 659 return false;
HomineLudens 0:a92a22490aaa 660 }
HomineLudens 0:a92a22490aaa 661
HomineLudens 0:a92a22490aaa 662 bool isDrawn(Sign originalBoard[MAX_GRID_SIZE][MAX_GRID_SIZE])
HomineLudens 0:a92a22490aaa 663 {
HomineLudens 0:a92a22490aaa 664 //All cells not None
HomineLudens 0:a92a22490aaa 665 for (char x=0; x<setBoardSize; x++) {
HomineLudens 0:a92a22490aaa 666 for (char y=0; y<setBoardSize; y++) {
HomineLudens 0:a92a22490aaa 667 if (originalBoard[x][y].symb==None) {
HomineLudens 0:a92a22490aaa 668 return false;
HomineLudens 0:a92a22490aaa 669 }
HomineLudens 0:a92a22490aaa 670 }
HomineLudens 0:a92a22490aaa 671 }
HomineLudens 0:a92a22490aaa 672 return true;
HomineLudens 0:a92a22490aaa 673 }
HomineLudens 0:a92a22490aaa 674
HomineLudens 0:a92a22490aaa 675
HomineLudens 0:a92a22490aaa 676 void AI(Symbol symb)
HomineLudens 0:a92a22490aaa 677 {
HomineLudens 0:a92a22490aaa 678 //Check if I can win
HomineLudens 0:a92a22490aaa 679 for (char x=0; x<setBoardSize; x++) {
HomineLudens 0:a92a22490aaa 680 for (char y=0; y<setBoardSize; y++) {
HomineLudens 0:a92a22490aaa 681 if (isWinner(board,symb,x,y)) {
HomineLudens 0:a92a22490aaa 682 //Place winning move
HomineLudens 0:a92a22490aaa 683 board[x][y].time=0;
HomineLudens 0:a92a22490aaa 684 board[x][y].symb=symb;
HomineLudens 0:a92a22490aaa 685 cursor.x=x;
HomineLudens 0:a92a22490aaa 686 cursor.y=y;
HomineLudens 0:a92a22490aaa 687 return;
HomineLudens 0:a92a22490aaa 688 }
HomineLudens 0:a92a22490aaa 689 }
HomineLudens 0:a92a22490aaa 690 }
HomineLudens 0:a92a22490aaa 691
HomineLudens 0:a92a22490aaa 692 //Check if anyone can win with a move
HomineLudens 0:a92a22490aaa 693 for(char p=0; p<setNumPlayers; p++) {
HomineLudens 0:a92a22490aaa 694 for (char x=0; x<setBoardSize; x++) {
HomineLudens 0:a92a22490aaa 695 for (char y=0; y<setBoardSize; y++) {
HomineLudens 0:a92a22490aaa 696 if (isWinner(board,players[p].symb,x,y)) {
HomineLudens 0:a92a22490aaa 697 //Place winning move
HomineLudens 0:a92a22490aaa 698 board[x][y].time=0;
HomineLudens 0:a92a22490aaa 699 board[x][y].symb=symb;
HomineLudens 0:a92a22490aaa 700 cursor.x=x;
HomineLudens 0:a92a22490aaa 701 cursor.y=y;
HomineLudens 0:a92a22490aaa 702 return;
HomineLudens 0:a92a22490aaa 703 }
HomineLudens 0:a92a22490aaa 704 }
HomineLudens 0:a92a22490aaa 705 }
HomineLudens 0:a92a22490aaa 706 }
HomineLudens 0:a92a22490aaa 707
HomineLudens 0:a92a22490aaa 708
HomineLudens 0:a92a22490aaa 709 //TODO:
HomineLudens 0:a92a22490aaa 710 //Check if I can win in 2 moves
HomineLudens 0:a92a22490aaa 711 //as homework
HomineLudens 0:a92a22490aaa 712
HomineLudens 0:a92a22490aaa 713 //place a random move
HomineLudens 0:a92a22490aaa 714 while(true) {
HomineLudens 0:a92a22490aaa 715 char x=random(0,setBoardSize-1);
HomineLudens 0:a92a22490aaa 716 char y=random(0,setBoardSize-1);
HomineLudens 0:a92a22490aaa 717 if(board[x][y].symb==None) {
HomineLudens 0:a92a22490aaa 718 board[x][y].time=0;
HomineLudens 0:a92a22490aaa 719 board[x][y].symb=symb;
HomineLudens 0:a92a22490aaa 720 cursor.x=x;
HomineLudens 0:a92a22490aaa 721 cursor.y=y;
HomineLudens 0:a92a22490aaa 722 return;
HomineLudens 0:a92a22490aaa 723 }
HomineLudens 0:a92a22490aaa 724 }
HomineLudens 0:a92a22490aaa 725 }
HomineLudens 0:a92a22490aaa 726
HomineLudens 0:a92a22490aaa 727 void updateGame()
HomineLudens 0:a92a22490aaa 728 {
HomineLudens 0:a92a22490aaa 729 //Move
HomineLudens 0:a92a22490aaa 730 if(players[playerTurn].AI) {
HomineLudens 0:a92a22490aaa 731 AI(players[playerTurn].symb);
HomineLudens 0:a92a22490aaa 732 gameState=Check;
HomineLudens 0:a92a22490aaa 733 } else {
HomineLudens 0:a92a22490aaa 734 if (btn.pressed(BTN_UP)) cursor.y-=1;
HomineLudens 0:a92a22490aaa 735 if (btn.pressed(BTN_DOWN)) cursor.y+=1;
HomineLudens 0:a92a22490aaa 736 if (btn.pressed(BTN_LEFT)) cursor.x-=1;
HomineLudens 0:a92a22490aaa 737 if (btn.pressed(BTN_RIGHT)) cursor.x+=1;
HomineLudens 0:a92a22490aaa 738
HomineLudens 0:a92a22490aaa 739 //Limit cursor to the board
HomineLudens 0:a92a22490aaa 740 if (cursor.x>=setBoardSize) cursor.x=0;
HomineLudens 0:a92a22490aaa 741 if (cursor.x<0) cursor.x=setBoardSize-1;
HomineLudens 0:a92a22490aaa 742 if (cursor.y>=setBoardSize) cursor.y=0;
HomineLudens 0:a92a22490aaa 743 if (cursor.y<0) cursor.y=setBoardSize-1;
HomineLudens 0:a92a22490aaa 744
HomineLudens 0:a92a22490aaa 745
HomineLudens 0:a92a22490aaa 746 if (btn.pressed(BTN_A)) {
HomineLudens 0:a92a22490aaa 747 if (board[cursor.x][cursor.y].symb==None) {
HomineLudens 0:a92a22490aaa 748 board[cursor.x][cursor.y].time=0;
HomineLudens 0:a92a22490aaa 749 board[cursor.x][cursor.y].symb=players[playerTurn].symb;
HomineLudens 0:a92a22490aaa 750 gameState=Check;
HomineLudens 0:a92a22490aaa 751 }
HomineLudens 0:a92a22490aaa 752 }
HomineLudens 0:a92a22490aaa 753 }
HomineLudens 0:a92a22490aaa 754
HomineLudens 0:a92a22490aaa 755 //Draw
HomineLudens 0:a92a22490aaa 756 drawBoard(boardPosition.x,boardPosition.y);
HomineLudens 0:a92a22490aaa 757 }
HomineLudens 0:a92a22490aaa 758
HomineLudens 0:a92a22490aaa 759 void updateCheck()
HomineLudens 0:a92a22490aaa 760 {
HomineLudens 0:a92a22490aaa 761
HomineLudens 0:a92a22490aaa 762 if(isWinner(board,players[playerTurn].symb)) {
HomineLudens 0:a92a22490aaa 763 cursor.x=-1;
HomineLudens 0:a92a22490aaa 764 cursor.y=-1;
HomineLudens 0:a92a22490aaa 765 gameState=Winner;
HomineLudens 0:a92a22490aaa 766 timer=game.getTime()+1500;
HomineLudens 0:a92a22490aaa 767 } else if (isDrawn(board)) {
HomineLudens 0:a92a22490aaa 768 cursor.x=-1;
HomineLudens 0:a92a22490aaa 769 cursor.y=-1;
HomineLudens 0:a92a22490aaa 770 gameState=Drawn;
HomineLudens 0:a92a22490aaa 771 timer=game.getTime()+1500;
HomineLudens 0:a92a22490aaa 772 } else {
HomineLudens 0:a92a22490aaa 773
HomineLudens 0:a92a22490aaa 774 gameState=Move;
HomineLudens 0:a92a22490aaa 775 }
HomineLudens 0:a92a22490aaa 776
HomineLudens 0:a92a22490aaa 777 //Next player
HomineLudens 0:a92a22490aaa 778 playerTurn++;
HomineLudens 0:a92a22490aaa 779 playerTurn=playerTurn%setNumPlayers;
HomineLudens 0:a92a22490aaa 780
HomineLudens 0:a92a22490aaa 781 //Draw
HomineLudens 0:a92a22490aaa 782 drawBoard(boardPosition.x,boardPosition.y);
HomineLudens 0:a92a22490aaa 783 }
HomineLudens 0:a92a22490aaa 784
HomineLudens 0:a92a22490aaa 785 void updateWin()
HomineLudens 0:a92a22490aaa 786 {
HomineLudens 0:a92a22490aaa 787 drawBoard(boardPosition.x,boardPosition.y);
HomineLudens 0:a92a22490aaa 788
HomineLudens 0:a92a22490aaa 789 //Winner line
HomineLudens 0:a92a22490aaa 790 if (winnerLine.time <100) winnerLine.time+=10;
HomineLudens 0:a92a22490aaa 791 drawWinningLine(boardPosition.x,boardPosition.y,winnerLine);
HomineLudens 0:a92a22490aaa 792
HomineLudens 0:a92a22490aaa 793 if (btn.pressed(BTN_A) || game.getTime()>timer) {
HomineLudens 0:a92a22490aaa 794 //move list symbols
HomineLudens 0:a92a22490aaa 795 for (int i=0; i<sizeof(scoreList)/sizeof(Sign); i++) {
HomineLudens 0:a92a22490aaa 796 scoreList[i].y+=SIGN_SIZE/2;
HomineLudens 0:a92a22490aaa 797 }
HomineLudens 0:a92a22490aaa 798
HomineLudens 0:a92a22490aaa 799 //add winner symbol
HomineLudens 0:a92a22490aaa 800 Sign winSign;
HomineLudens 0:a92a22490aaa 801 winSign.x=disp.width-(SIGN_SIZE/2);
HomineLudens 0:a92a22490aaa 802 winSign.y=SIGN_SIZE+SIGN_SIZE/2;
HomineLudens 0:a92a22490aaa 803 winSign.symb=winnerLine.symb;
HomineLudens 0:a92a22490aaa 804 winSign.diameter=SIGN_SIZE/2;
HomineLudens 0:a92a22490aaa 805 scoreList[scoreListIndx]=winSign;
HomineLudens 0:a92a22490aaa 806 scoreListIndx=(scoreListIndx+1)%(sizeof(scoreList)/sizeof(Sign));
HomineLudens 0:a92a22490aaa 807
HomineLudens 0:a92a22490aaa 808 gameState=InitGame;
HomineLudens 0:a92a22490aaa 809 }
HomineLudens 0:a92a22490aaa 810 disp.color=0;
HomineLudens 0:a92a22490aaa 811 disp.fillRectangle(55,disp.height/2-2,100,10);
HomineLudens 0:a92a22490aaa 812 disp.color=2;
HomineLudens 0:a92a22490aaa 813 disp.println(55,disp.height/2,"There's a winner!");
HomineLudens 0:a92a22490aaa 814 }
HomineLudens 0:a92a22490aaa 815
HomineLudens 0:a92a22490aaa 816 void updateDrawn()
HomineLudens 0:a92a22490aaa 817 {
HomineLudens 0:a92a22490aaa 818 drawBoard(boardPosition.x,boardPosition.y);
HomineLudens 0:a92a22490aaa 819
HomineLudens 0:a92a22490aaa 820 disp.color=0;
HomineLudens 0:a92a22490aaa 821 disp.fillRectangle(55,disp.height/2-2,80,10);
HomineLudens 0:a92a22490aaa 822 disp.color=2;
HomineLudens 0:a92a22490aaa 823 disp.print(60,disp.height/2,"It's a drawn");
HomineLudens 0:a92a22490aaa 824
HomineLudens 0:a92a22490aaa 825 if (btn.pressed(BTN_A) || game.getTime()>timer) {
HomineLudens 0:a92a22490aaa 826 gameState=InitGame;
HomineLudens 0:a92a22490aaa 827 }
HomineLudens 0:a92a22490aaa 828 }
HomineLudens 0:a92a22490aaa 829
HomineLudens 0:a92a22490aaa 830
HomineLudens 0:a92a22490aaa 831 int main ()
HomineLudens 0:a92a22490aaa 832 {
HomineLudens 0:a92a22490aaa 833 initMenu();
HomineLudens 0:a92a22490aaa 834 game.begin();
HomineLudens 0:a92a22490aaa 835
HomineLudens 0:a92a22490aaa 836 //load palette
HomineLudens 0:a92a22490aaa 837 disp.palette[0]=COLOR_BLACK;
HomineLudens 0:a92a22490aaa 838 disp.palette[1]=COLOR_WHITE;
HomineLudens 0:a92a22490aaa 839 disp.palette[2]=COLOR_GREEN;
HomineLudens 0:a92a22490aaa 840 disp.palette[3]=COLOR_RED;
HomineLudens 0:a92a22490aaa 841
HomineLudens 0:a92a22490aaa 842 while (game.isRunning()) {
HomineLudens 0:a92a22490aaa 843 if (game.update()) {
HomineLudens 0:a92a22490aaa 844 //Exit to menu
HomineLudens 0:a92a22490aaa 845 if(btn.pressed((BTN_C))) {
HomineLudens 0:a92a22490aaa 846 gameState=Menu;
HomineLudens 0:a92a22490aaa 847 }
HomineLudens 0:a92a22490aaa 848
HomineLudens 0:a92a22490aaa 849 //Game states
HomineLudens 0:a92a22490aaa 850 switch (gameState) {
HomineLudens 0:a92a22490aaa 851 case Menu:
HomineLudens 0:a92a22490aaa 852 updateMenu();
HomineLudens 0:a92a22490aaa 853 break;
HomineLudens 0:a92a22490aaa 854 case InitGame:
HomineLudens 0:a92a22490aaa 855 initGame();
HomineLudens 0:a92a22490aaa 856 break;
HomineLudens 0:a92a22490aaa 857 case Move:
HomineLudens 0:a92a22490aaa 858 updateGame();
HomineLudens 0:a92a22490aaa 859 break;
HomineLudens 0:a92a22490aaa 860 case Check:
HomineLudens 0:a92a22490aaa 861 updateCheck();
HomineLudens 0:a92a22490aaa 862 break;
HomineLudens 0:a92a22490aaa 863 case Winner:
HomineLudens 0:a92a22490aaa 864 updateWin();
HomineLudens 0:a92a22490aaa 865 break;
HomineLudens 0:a92a22490aaa 866 case Drawn:
HomineLudens 0:a92a22490aaa 867 updateDrawn();
HomineLudens 0:a92a22490aaa 868 break;
HomineLudens 0:a92a22490aaa 869 default:
HomineLudens 0:a92a22490aaa 870 break;
HomineLudens 0:a92a22490aaa 871 }
HomineLudens 0:a92a22490aaa 872 }
HomineLudens 0:a92a22490aaa 873 }
HomineLudens 0:a92a22490aaa 874
HomineLudens 0:a92a22490aaa 875 return 1;
HomineLudens 1:cdc038225cf5 876 }