Browse Source

Read puzzles and randomly select one to play

This was a major milestone!
master
Macoy Madson 3 years ago
parent
commit
faa6254ee6
  1. 3
      Build.sh
  2. 19
      src/Decompression.cake
  3. 125
      src/Main.cake

3
Build.sh

@ -10,6 +10,7 @@ CAKELISP=./Dependencies/cakelisp/bin/cakelisp
# After relocation, this will be able to be simply .
KITTY_DIR=../..
$CAKELISP --execute $KITTY_DIR/src/Decompression.cake || exit $?
# Uncomment to generate data/puzzles.txt
# $CAKELISP --execute $KITTY_DIR/src/Decompression.cake || exit $?
$CAKELISP --execute $KITTY_DIR/src/Main.cake || exit $?

19
src/Decompression.cake

@ -90,20 +90,25 @@
(defun-local process-puzzle-data (buffer (* char) num-bytes-this-read int
user-data (* void) &return bool)
(var work-in-progress-line (* puzzle-line-buffer) (type-cast user-data (* puzzle-line-buffer)))
(var current-char (* char) buffer)
(while (< (- current-char buffer) num-bytes-this-read)
(cond
((= '\n' (deref current-char))
((= '\n' (deref current-char)) ;; Found puzzle delimiter
(set (deref (path work-in-progress-line > buffer-write)) 0)
;; Output puzzle
(when (= 0 (mod (path work-in-progress-line > num-puzzles-read) g-puzzle-skip-count))
(printf "%s\n" (path work-in-progress-line > buffer))
(when (path work-in-progress-line > file-out)
(fprintf (path work-in-progress-line > file-out) "%s\n"
(path work-in-progress-line > buffer))))
(set (path work-in-progress-line > buffer-write)
(path work-in-progress-line > buffer))
(incr (path work-in-progress-line > num-puzzles-read)))
(true
(true ;; Reading a puzzle in
(set (deref (path work-in-progress-line > buffer-write)) (deref current-char))
(incr (path work-in-progress-line > buffer-write))
(when (>= (- (path work-in-progress-line > buffer-write)
@ -113,15 +118,19 @@
(return false))))
(incr current-char))
(return true))
(defun main (&return int)
(var bz2-file (* (const char)) "assets/rush.txt.bz2")
;; For when the read buffer straddles a single puzzle
;; 46 chars max per puzzle, plus newline, plus room for null terminator for easy printing
(var work-in-progress-buffer ([] 48 char) (array 0))
(var file-out (* FILE) (fopen "data/puzzles.txt" "w"))
(unless file-out
(printf "Could not open output file\n")
(return 1))
(fprintf file-out "%d\n" g-num-puzzles-to-read)
;; For when the read buffer straddles a single puzzle
;; 46 chars max per puzzle, plus newline, plus room for null terminator for easy printing
(var work-in-progress-buffer ([] 48 char) (array 0))
(var work-in-progress-line puzzle-line-buffer
(array work-in-progress-buffer (array-size work-in-progress-buffer)
work-in-progress-buffer 0 file-out))

125
src/Main.cake

@ -14,7 +14,7 @@
"Decompression.cake" ;; kitty-gridlock
&comptime-only "Macros.cake") ;; cakelisp/runtime
(c-import "<stdio.h>"
(c-import "<stdio.h>" "<stdlib.h>"
"SDL.h" "SDL_syswm.h" "SDL_timer.h" "SDL_render.h"
;; For round()
"<math.h>")
@ -262,51 +262,89 @@
;; I used lowercase ~o~ instead of periods ~.~ for the empty cells in the database so that the entire board description can be selected with a double-click.
;; Example format:
;; 60 IBBxooIooLDDJAALooJoKEEMFFKooMGGHHHM 2332
(defun-local game-board-load (fogleman-board-string (* (const char)) &return bool)
(defun-local game-board-load (board-string (* (const char)) &return bool)
(game-board-reset-pieces)
(var num-moves int 0)
(var num-states int 0)
(var pieces-read bool false)
(var buffer ([] 37 char) (array 0))
(var write-char (* char) buffer)
(var current-char (* (const char)) fogleman-board-string)
(while (deref current-char)
(var board-char (* (const char)) board-string)
(while (< (- board-char board-string) 36)
(cond
;; Space field delimiter
((= (deref current-char) (space-hack))
(cond
((not num-moves)
(set num-moves (atoi buffer)))
(true ;; Reading pieces
(var board-char (* (const char)) buffer)
(while (deref board-char)
(cond
((= (deref board-char) 'o')
(debug-log "empty\n")) ;; Empty space
(true ;; Wall or piece
(var char-index int (- board-char buffer))
(var piece-cell-position grid-vec2 (array (% char-index g-game-board-grid-size)
(/ char-index g-game-board-grid-size)))
(debug-log "[%d] '%c' = (%d %d)\n" char-index (deref board-char) (vec-xy piece-cell-position))
(game-board-piece-from-char (deref board-char) piece-cell-position)))
(incr board-char))))
;; Reset buffer
(memset buffer 0 (sizeof buffer))
(set write-char buffer))
(true
(set (deref write-char) (deref current-char))
(incr write-char)))
(incr current-char))
(set num-states (atoi buffer))
((= (deref board-char) 'o')
(debug-log "empty\n")) ;; Empty space
(true ;; Wall or piece
(var char-index int (- board-char board-string))
(var piece-cell-position grid-vec2 (array (% char-index g-game-board-grid-size)
(/ char-index g-game-board-grid-size)))
(debug-log "[%d] '%c' = (%d %d)\n" char-index (deref board-char) (vec-xy piece-cell-position))
(game-board-piece-from-char (deref board-char) piece-cell-position)))
(incr board-char))
(game-board-sync-occupied-state)
(printf "Board loaded. %d moves, %d states.\n" num-moves num-states)
(printf "%s\n" fogleman-board-string)
(return true))
(defstruct-local puzzle-data
num-moves char
num-states int
board ([] 36 char))
(var g-puzzle-list (* puzzle-data) null)
(var g-num-puzzles int 0)
(defun-local read-puzzles (&return bool)
(var puzzles-file (* FILE) (fopen (in-data-dir "puzzles.txt") "r"))
(unless puzzles-file
(printf "Failed to load puzzles. You may need to run Decompression.cake (see Build.sh)\n")
(return false))
;; 48 = max length of a single line in puzzles .txt
(var line-buffer ([] 48 char) (array 0))
(unless (fgets line-buffer (array-size line-buffer) puzzles-file)
(printf "Puzzle file malformed\n") (return false))
(var num-puzzles int (atoi line-buffer))
(printf "Reading %d puzzles\n" num-puzzles)
(when g-puzzle-list (free (type-cast g-puzzle-list (* void))))
(set g-num-puzzles num-puzzles)
(set g-puzzle-list (type-cast (calloc g-num-puzzles (sizeof (type puzzle-data))) (* puzzle-data)))
;; Read puzzles line by line
(var current-puzzle (* puzzle-data) g-puzzle-list)
(while (and (fgets line-buffer (array-size line-buffer) puzzles-file)
(< (- current-puzzle g-puzzle-list) g-num-puzzles))
(var num-moves int 0)
(var num-states int 0)
(var pieces-read bool false)
(var buffer ([] 37 char) (array 0))
(var write-char (* char) buffer)
(var current-char (* (const char)) line-buffer)
(while (deref current-char)
(cond
;; Space field delimiter
((= (deref current-char) (space-hack))
(cond
((not num-moves)
(set num-moves (atoi buffer)))
(true ;; Copy pieces
;; TODO Magic number
(memcpy (path current-puzzle > board) buffer 36)
(set pieces-read true)))
;; Reset buffer after space
(memset buffer 0 (sizeof buffer))
(set write-char buffer))
((= (deref current-char) '\n')
(break))
(true
(set (deref write-char) (deref current-char))
(incr write-char)))
(incr current-char))
(set (path current-puzzle > num-moves) num-moves)
(set num-states (atoi buffer))
(set (path current-puzzle > num-states) num-states)
(incr current-puzzle))
(fclose puzzles-file)
(return (> g-num-puzzles 0)))
(defun-local game-piece-grid-position-to-screen-position (piece (* (const board-piece)) &return vec2)
(var piece-position vec2 (array (type-cast (vec-x (path piece > grid-position)) float)
(type-cast (vec-y (path piece > grid-position)) float)))
@ -646,6 +684,7 @@ Rush Hour database from Michael Fogleman.\n\n")
;; (unless (bunzip-decompress puzzle-database-filename)
;; (return 1))
;; (sdl-print-time-delta start-load-ticks "Database loaded")
(unless (read-puzzles) (return 1))
(var background-texture (* SDL_Texture) (sdl-texture-from-bmp (in-data-dir "Board.bmp")
renderer))
@ -694,8 +733,9 @@ Rush Hour database from Michael Fogleman.\n\n")
(sdl-print-time-delta start-load-ticks "Textures loaded")
;; (game-board-load "60 IBBxooIooLDDJAALooJoKEEMFFKooMGGHHHM 2332")
(game-board-load "07 BBBoooooFxooAAFGooEooGooEDDDoooooooo 478")
;; (game-board-load "IBBxooIooLDDJAALooJoKEEMFFKooMGGHHHM")
(srand (type-cast (SDL_GetPerformanceCounter) int))
(game-board-load (field (at (mod (rand) g-num-puzzles) g-puzzle-list) board))
;;
;; Game loop
;;
@ -821,7 +861,7 @@ Rush Hour database from Michael Fogleman.\n\n")
(when (do-button (addr in-state) (array 0.f 0.f) (array 166.f 166.f) renderer theme-button-texture)
(set is-day-mode (not is-day-mode)))
(when (do-button (addr in-state) (array 300.f 0.f) (array 166.f 166.f) renderer undo-button-texture)
(set is-day-mode (not is-day-mode))))
(game-board-load (field (at (mod (rand) g-num-puzzles) g-puzzle-list) board))))
(when (is-in-win-state)
(var dest-rect SDL_Rect (array 60 140 960 500))
@ -936,6 +976,8 @@ Rush Hour database from Michael Fogleman.\n\n")
(when exit-reason
(printf "Exiting. Reason: %s\n" exit-reason))
(when g-puzzle-list (free (type-cast g-puzzle-list (* void))))
(SDL_DestroyTexture background-texture)
(set background-texture null)
(SDL_DestroyTexture grid-texture)
@ -952,6 +994,7 @@ Rush Hour database from Michael Fogleman.\n\n")
(SDL_DestroyRenderer renderer)
(sdl-shutdown window)
(return 0))
;;

Loading…
Cancel
Save