From 91290acec689d1924661700b00e1435b141819db Mon Sep 17 00:00:00 2001 From: Jeremy Rand Date: Wed, 15 Jul 2015 21:05:34 -0500 Subject: [PATCH] Some optimization and draw the scratch values. --- a2sudoku/game.c | 42 ++++---- a2sudoku/game.h | 5 + a2sudoku/ui.c | 254 +++++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 267 insertions(+), 34 deletions(-) diff --git a/a2sudoku/game.c b/a2sudoku/game.c index 365298a..714fde9 100644 --- a/a2sudoku/game.c +++ b/a2sudoku/game.c @@ -149,27 +149,23 @@ bool isSquareInvalid(tPos col, tPos row) } -bool refreshInvalid(tPos col, tPos row) +void refreshInvalid(tPos col, tPos row) { - bool update = false; tPos x, y; + tGameSquare *square; + bool newInvalid; for (y = 0; y < BOARD_SIZE; y++) { for (x = 0; x < BOARD_SIZE; x++) { - bool newInvalid = isSquareInvalid(x, y); - if (newInvalid != SQUARE_XY(x, y).invalid) { - SQUARE_XY(x, y).invalid = isSquareInvalid(x, y); - - if ((col == x) && - (row == y)) - update = true; - else - refreshPos(x, y); + newInvalid = isSquareInvalid(x, y); + square = &(SQUARE_XY(x, y)); + + if (newInvalid != square->invalid) { + square->invalid = newInvalid; + refreshPos(x, y); } } } - - return update; } @@ -177,6 +173,7 @@ bool setValueAtPos(tPos x, tPos y, tSquareVal val) { tGameSquare *square = &(SQUARE_XY(x, y)); bool update = false; + bool checkValues = false; bool correct; if (square->knownAtStart) { @@ -186,6 +183,7 @@ bool setValueAtPos(tPos x, tPos y, tSquareVal val) if (square->value != val) { square->value = val; update = true; + checkValues = true; } if (square->scratchValues != 0) { @@ -193,17 +191,19 @@ bool setValueAtPos(tPos x, tPos y, tSquareVal val) update = true; } - correct = checkValueAtPos(theGame.puzzle, val, x, y); - if (square->correct != correct) { - square->correct = correct; - update = true; + if (checkValues) { + correct = checkValueAtPos(theGame.puzzle, val, x, y); + if (square->correct != correct) { + square->correct = correct; + update = true; + } } - if (refreshInvalid(x, y)) - update = true; - if (update) - refreshPos(x, y); + refreshPos(x,y); + + if (checkValues) + refreshInvalid(x, y); return true; } diff --git a/a2sudoku/game.h b/a2sudoku/game.h index 2ab54b0..9813e80 100644 --- a/a2sudoku/game.h +++ b/a2sudoku/game.h @@ -13,6 +13,11 @@ #define __a2sudoku__game__ +// Macros + +#define SCRATCH_TEST(scratch, val) ((scratch) & (0x1 << val)) + + // Typedefs typedef uint16_t tScratchValues; diff --git a/a2sudoku/ui.c b/a2sudoku/ui.c index 1b80b71..9a34953 100644 --- a/a2sudoku/ui.c +++ b/a2sudoku/ui.c @@ -41,6 +41,12 @@ extern char a2e_hi; ((BOARD_SIZE + 1) * THIN_LINE_HEIGHT) + \ (((BOARD_SIZE / SUBSQUARE_SIZE) + 1) * (THICK_LINE_HEIGHT - THIN_LINE_HEIGHT))) +#define WON_WIDTH 100 +#define WON_HEIGHT 55 + +#define SCRATCH_WIDTH 9 +#define SCRATCH_HEIGHT 6 + // Globals; @@ -52,20 +58,12 @@ int screenSquaresY[BOARD_SIZE]; // Implementation -void initUI(void) +void drawGrid(void) { - static bool tgi_inited = false; tPos pos; int xPos = 0; int yPos = 0; - - if (tgi_inited) - return; - - // Install drivers - tgi_install(&a2e_hi); - - tgi_init(); + tgi_clear(); tgi_setcolor(COLOR_WHITE); @@ -92,6 +90,20 @@ void initUI(void) xPos += SQUARE_WIDTH; yPos += SQUARE_HEIGHT; } +} + + +void initUI(void) +{ + static bool tgi_inited = false; + + if (tgi_inited) + return; + + // Install drivers + tgi_install(&a2e_hi); + + tgi_init(); tgi_inited = true; } @@ -121,7 +133,7 @@ void displayInstructions(void) "subsquare. Move the cursor with I-J-K-L" "or the arrow keys. Press a number key\n" "to enter a value. Press a number key\n" - "while holding shift or closed apple to\n" + "while holding shift or open apple to\n" "toggle a scratch value. Press 0 to\n" "clear a square.\n" "\n" @@ -146,6 +158,143 @@ void displayInstructions(void) } +void drawOne(int screenX, int screenY) +{ + tgi_line(screenX + 2, screenY, screenX + 2, screenY + 3); + tgi_line(screenX + 1, screenY + 4, screenX + 3, screenY + 4); + tgi_setpixel(screenX + 1, screenY + 1); +} + + +void drawTwo(int screenX, int screenY) +{ + tgi_setpixel(screenX, screenY + 1); + tgi_line(screenX + 1, screenY, screenX + 3, screenY); + tgi_line(screenX + 4, screenY + 1, screenX, screenY + 4); + tgi_lineto(screenX + 4, screenY + 4); +} + + +void drawThree(int screenX, int screenY) +{ + tgi_line(screenX + 1, screenY, screenX + 3, screenY); + tgi_line(screenX + 1, screenY + 2, screenX + 3, screenY + 2); + tgi_line(screenX + 1, screenY + 4, screenX + 3, screenY + 4); + tgi_setpixel(screenX + 4, screenY + 1); + tgi_setpixel(screenX + 4, screenY + 3); +} + + +void drawFour(int screenX, int screenY) +{ + tgi_line(screenX, screenY + 1, screenX, screenY + 2); + tgi_lineto(screenX + 4, screenY + 2); + tgi_line(screenX + 3, screenY, screenX + 3, screenY + 4); +} + + +void drawFive(int screenX, int screenY) +{ + tgi_line(screenX + 4, screenY, screenX, screenY); + tgi_lineto(screenX, screenY + 2); + tgi_lineto(screenX + 3, screenY + 2); + tgi_line(screenX, screenY + 4, screenX + 3, screenY + 4); + tgi_setpixel(screenX + 4, screenY + 3); +} + + +void drawSix(int screenX, int screenY) +{ + tgi_line(screenX + 3, screenY, screenX, screenY + 3); + tgi_line(screenX + 1, screenY + 4, screenX + 3, screenY + 4); + tgi_line(screenX + 1, screenY + 2, screenX + 3, screenY + 2); + tgi_setpixel(screenX + 4, screenY + 3); +} + + +void drawSeven(int screenX, int screenY) +{ + tgi_line(screenX, screenY, screenX + 4, screenY); + tgi_line(screenX + 4, screenY + 1, screenX + 1, screenY + 4); +} + + +void drawEight(int screenX, int screenY) +{ + tgi_line(screenX + 1, screenY, screenX + 3, screenY); + tgi_line(screenX + 1, screenY + 2, screenX + 3, screenY + 2); + tgi_line(screenX + 1, screenY + 4, screenX + 3, screenY + 4); + tgi_setpixel(screenX, screenY + 1); + tgi_setpixel(screenX, screenY + 3); + tgi_setpixel(screenX + 4, screenY + 1); + tgi_setpixel(screenX + 4, screenY + 3); +} + + +void drawNine(int screenX, int screenY) +{ + tgi_line(screenX + 1, screenY, screenX + 3, screenY); + tgi_line(screenX + 1, screenY + 2, screenX + 3, screenY + 2); + tgi_line(screenX + 4, screenY + 1, screenX + 4, screenY + 4); + tgi_setpixel(screenX, screenY + 1); +} + + +void drawScratch(tPos x, tPos y, tScratchValues scratch) +{ + int screenX = screenSquaresX[x] + 1; + int screenY = screenSquaresY[y] + 1; + + if (SCRATCH_TEST(scratch, 1)) { + drawOne(screenX, screenY); + } + + screenX += SCRATCH_WIDTH; + if (SCRATCH_TEST(scratch, 2)) { + drawTwo(screenX, screenY); + } + + screenX += SCRATCH_WIDTH; + if (SCRATCH_TEST(scratch, 3)) { + drawThree(screenX, screenY); + } + + screenX = screenSquaresX[x] + 1; + screenY += SCRATCH_HEIGHT; + if (SCRATCH_TEST(scratch, 4)) { + drawFour(screenX, screenY); + } + + screenX += SCRATCH_WIDTH; + if (SCRATCH_TEST(scratch, 5)) { + drawFive(screenX, screenY); + } + + screenX += SCRATCH_WIDTH; + if (SCRATCH_TEST(scratch, 6)) { + drawSix(screenX, screenY); + } + + screenX = screenSquaresX[x] + 1; + screenY += SCRATCH_HEIGHT; + if (SCRATCH_TEST(scratch, 7)) { + drawSeven(screenX, screenY); + } + + screenX += SCRATCH_WIDTH; + if (SCRATCH_TEST(scratch, 8)) { + drawEight(screenX, screenY); + } + + screenX += SCRATCH_WIDTH; + if (SCRATCH_TEST(scratch, 9)) { + drawNine(screenX, screenY); + } + + tgi_setcolor(COLOR_WHITE); +} + + void updatePos(tPos x, tPos y, tSquareVal val, tScratchValues scratch, bool correct, bool invalid) { int screenX = screenSquaresX[x]; @@ -169,6 +318,8 @@ void updatePos(tPos x, tPos y, tSquareVal val, tScratchValues scratch, bool corr if (invalid) tgi_line(screenX, edgeY, edgeX, screenY); + } else if (scratch != 0) { + drawScratch(x, y, scratch); } if ((cursorX == x) && @@ -181,6 +332,25 @@ void updatePos(tPos x, tPos y, tSquareVal val, tScratchValues scratch, bool corr } +void youWon(void) +{ + int wonX = (TOTAL_WIDTH - WON_WIDTH) / 2; + int wonY = (TOTAL_HEIGHT - WON_HEIGHT) / 2; + char *line1 = "You solved it!"; + char *line2 = "Press any key"; + int textHeight = tgi_textheight(line1); + + tgi_setcolor(COLOR_BLACK); + tgi_bar(wonX, wonY, wonX + WON_WIDTH, wonY + WON_HEIGHT); + + tgi_setcolor(COLOR_WHITE); + tgi_outtextxy(wonX + 10, wonY + (textHeight * 2), line1); + tgi_outtextxy(wonX + 7, wonY + (textHeight * 4), line2); + + cgetc(); +} + + bool playGame(void) { initUI(); @@ -188,10 +358,20 @@ bool playGame(void) cursorX = 0; cursorY = 0; + drawGrid(); + startGame(updatePos); while (true) { - char ch = cgetc(); + char ch; + bool shouldNotBeep = true; + + if (isPuzzleSolved()) { + youWon(); + return true; + } + + ch = cgetc(); switch (ch) { case 'h': @@ -261,8 +441,56 @@ bool playGame(void) case '7': case '8': case '9': - setValueAtPos(cursorX, cursorY, ch - '0'); + shouldNotBeep = setValueAtPos(cursorX, cursorY, ch - '0'); break; + + case CH_F1: + case '!': + shouldNotBeep = toggleScratchValueAtPos(cursorX, cursorY, 1); + break; + + case CH_F2: + case '@': + shouldNotBeep = toggleScratchValueAtPos(cursorX, cursorY, 2); + break; + + case CH_F3: + case '#': + shouldNotBeep = toggleScratchValueAtPos(cursorX, cursorY, 3); + break; + + case CH_F4: + case '$': + shouldNotBeep = toggleScratchValueAtPos(cursorX, cursorY, 4); + break; + + case CH_F5: + case '%': + shouldNotBeep = toggleScratchValueAtPos(cursorX, cursorY, 5); + break; + + case CH_F6: + case '^': + shouldNotBeep = toggleScratchValueAtPos(cursorX, cursorY, 6); + break; + + case CH_F7: + case '&': + shouldNotBeep = toggleScratchValueAtPos(cursorX, cursorY, 7); + break; + + case CH_F8: + case '*': + shouldNotBeep = toggleScratchValueAtPos(cursorX, cursorY, 8); + break; + + case CH_F9: + case '(': + shouldNotBeep = toggleScratchValueAtPos(cursorX, cursorY, 9); + break; + } + if (!shouldNotBeep) { + printf("\007"); } }