Solitaire for the TI-84 Plus CE!
at main 150 lines 3.9 kB view raw
1// Kabufuda Solitaire / KBFDSLTR for the TI-84 Plus CE 2// Copyright (C) 2024 euphory 3// 4// This program is free software: you can redistribute it and/or modify 5// it under the terms of the GNU General Public License as published by 6// the Free Software Foundation, either version 3 of the License, or 7// (at your option) any later version. 8// 9// This program is distributed in the hope that it will be useful, 10// but WITHOUT ANY WARRANTY; without even the implied warranty of 11// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12// GNU General Public License for more details. 13// 14// You should have received a copy of the GNU General Public License 15// along with this program. If not, see <https://www.gnu.org/licenses/>. 16 17#include "ops.h" 18 19#include <stdlib.h> 20#include <fileioc.h> 21 22#include "variables.h" 23#include "save.h" 24 25unsigned char cursorStack; 26unsigned char cursorIndex; 27enum cursorMode_t cursorMode; 28unsigned char selectedCard; 29unsigned char selectedQty; 30unsigned char orgStack; 31unsigned char orgIndex; 32 33void start() 34{ 35 loadWins(); 36 37 // fill tableau and free cells with empty space 38 for (unsigned char i = 0; i < NUM_FREECELLS; i++) 39 freeCells[i] = 11; 40 for (unsigned char i = 0; i < NUM_TABLSLOTS; i++) 41 for (unsigned char j = 0; j < TABL_STACK_SIZE; j++) 42 tableau[i][j] = 11; 43 44 load(); // will call deal() as well if necessary 45 46 // set initial variables 47 cursorMode = SELECT; 48 cursorStack = NUM_FREECELLS; 49 maxCursorIndex(); 50 selectedCard = tableau[cursorStack][cursorIndex]; 51} 52 53bool canGrabCard() 54{ 55 if (cursorStack < NUM_FREECELLS) return freeCells[cursorStack] < 11; 56 57 if (tableau[cursorStack - NUM_FREECELLS][0] > 11) return false; 58 for (unsigned char i = cursorIndex + 1; i < TABL_STACK_SIZE; i++) 59 { 60 const unsigned char x = tableau[cursorStack - NUM_FREECELLS][i]; 61 if (x == 11) return true; 62 if (x != selectedCard) return false; 63 } 64 65 return true; 66} 67 68bool canDropCard() 69{ 70 if (cursorStack < NUM_FREECELLS) 71 { 72 const unsigned char x = freeCells[cursorStack]; 73 if (cursorStack < fcUnlocked) 74 { 75 if (selectedQty == 1 || selectedQty == 4) return x == 11; 76 else return x == selectedCard && selectedQty == 3; 77 } 78 else return false; 79 } 80 else if (cursorIndex == 0) return true; 81 else return tableau[cursorStack - NUM_FREECELLS][cursorIndex - 1] == selectedCard; 82} 83 84bool checkTableauCollapse(unsigned char stackToCheck) 85{ 86 const unsigned char x = tableau[stackToCheck][0]; 87 for (unsigned char i = 1; i < 5; i++) 88 { 89 const unsigned char y = tableau[stackToCheck][i]; 90 if (i == 4 && y == 11) return true; 91 if (y != x) return false; 92 } 93 94 return false; 95} 96 97void dropCard() 98{ 99 if (cursorStack == orgStack) return; 100 101 unsigned char const prevProgress = progress; 102 103 if (cursorStack < NUM_FREECELLS) 104 { 105 if (selectedQty == 1) freeCells[cursorStack] = selectedCard; 106 else 107 { 108 progress++; 109 freeCells[cursorStack] = 12 + selectedCard; 110 } 111 } 112 else 113 { 114 for (unsigned char i = cursorIndex; i < cursorIndex + selectedQty; i++) 115 tableau[cursorStack - NUM_FREECELLS][i] = selectedCard; 116 if (checkTableauCollapse(cursorStack - NUM_FREECELLS)) 117 { 118 fcUnlocked++; 119 progress++; 120 tableau[cursorStack - NUM_FREECELLS][0] = selectedCard + 12; 121 for (int i = 1; i < 4; i++) tableau[cursorStack - NUM_FREECELLS][i] = 11; 122 } 123 } 124 125 if (orgStack < NUM_FREECELLS) freeCells[orgStack] = 11; 126 else for (unsigned char i = orgIndex; i < orgIndex + selectedQty; i++) 127 tableau[orgStack - NUM_FREECELLS][i] = 11; 128 129 if (progress == 10 && prevProgress < 10) numWins++; 130} 131 132void maxCursorIndex() 133{ 134 if (cursorStack < NUM_FREECELLS) return; 135 136 cursorIndex = TABL_STACK_SIZE - 1; 137 while (tableau[cursorStack - NUM_FREECELLS][cursorIndex] == 11 && cursorIndex > 0) cursorIndex--; 138} 139 140bool cursorOnCollapsed() 141{ 142 return cursorStack < NUM_FREECELLS ? freeCells[cursorStack] > 11 143 : tableau[cursorStack - NUM_FREECELLS][0] > 11; 144} 145 146bool cursorOnLocked() 147{ 148 return cursorStack >= fcUnlocked && cursorStack < NUM_FREECELLS; 149} 150