coords-model.scm 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. ;; ===========
  2. ;; EXPLANATION
  3. ;; ===========
  4. ;; The coordinate model defines, how indices to the bits of a bit board are mapped to coordinates
  5. ;; and vice versa. It maps the lowest index to the lowest coordinates, which are the coordinates
  6. ;; with lowerst row and column ids. How those row and column ids are interpreted and translated into
  7. ;; game coordinates will depend on the game specific implementation.
  8. ;; For example: A chess board as typically displayed, will have the square A1 in the lower left
  9. ;; corner. However, this might not be mapped to the lowest index of the bits of the bit
  10. ;; board. Instead a possible mapping could map A8 to the lowest index and H1 to the highest index,
  11. ;; which could make sense from the perspective of screen display, where usually the top left corner
  12. ;; is assigned the coordinates (0,0).
  13. ;; It would then be a good idea to write a translation function, which takes care of that mapping.
  14. (define-module (coords-model)
  15. #:export
  16. (get-row-part
  17. get-col-part
  18. make-coords
  19. index->coords
  20. coords->index))
  21. (define (get-row-part coords)
  22. (car coords))
  23. (define (get-col-part coords)
  24. (cdr coords))
  25. (define (make-coords row-idx col-idx)
  26. (cons row-idx col-idx))
  27. (define (index->coords index row-count col-count)
  28. (cond
  29. [(>= index (* row-count col-count))
  30. (throw 'index-error
  31. (simple-format #f "expected index < ~a" (* row-count col-count))
  32. index row-count col-count)]
  33. [(not (exact-integer? index))
  34. (throw 'index-error "expected index to be exact integer" index)]
  35. [(not (>= index 0))
  36. (throw 'index-error "expected index to be greater than 0 or equal to 0" index)]
  37. [(let* ([row-coord (floor (/ index col-count))]
  38. [col-coord (- index (* row-coord col-count))])
  39. (make-coords row-coord col-coord))]))
  40. (define (coords->index coords row-count col-count)
  41. (let ([row-coord (get-row-part coords)]
  42. [col-coord (get-col-part coords)])
  43. (cond
  44. [(or (< row-coord 0)
  45. (< col-coord 0)
  46. (>= row-coord row-count)
  47. (>= col-coord col-count))
  48. (throw 'index-error "index out of bounds" row-coord col-coord row-count col-count)]
  49. [else (+ (* row-coord col-count) col-coord)])))