board.go 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. package board
  2. import (
  3. "bytes"
  4. "encoding/json"
  5. "fmt"
  6. "io"
  7. "log"
  8. "math/rand"
  9. )
  10. type Board struct {
  11. Cols int `json:"cols"`
  12. Rows int `json:"rows"`
  13. Tiles []Tile `json:"tiles"`
  14. }
  15. const maxIceWidth = 26
  16. // Create a new randomly generated board.
  17. func New(cols, rows int) *Board {
  18. b := &Board{cols, rows, make([]Tile, rows*cols)}
  19. for y := 0; y < rows; y++ {
  20. for x := 0; x < cols; x++ {
  21. b.randomizeTile(x, y)
  22. }
  23. }
  24. return b
  25. }
  26. // Set the tile in column x and row y to val.
  27. func (b Board) Set(x, y int, val Tile) {
  28. b.Tiles[y*b.Cols+x] = val
  29. }
  30. // Get the tile in column x and row y.
  31. func (b Board) Get(x, y int) Tile {
  32. return b.Tiles[y*b.Cols+x]
  33. }
  34. func (b Board) String() string {
  35. var buffer bytes.Buffer
  36. for y := 0; y < b.Rows; y++ {
  37. for x := 0; x < b.Cols; x++ {
  38. buffer.WriteString(b.Get(x, y).String())
  39. }
  40. buffer.WriteString(fmt.Sprintln())
  41. }
  42. return buffer.String()
  43. }
  44. type jsonTile struct {
  45. X int `json:"x"`
  46. Y int `json:"y"`
  47. Type string `json:"type"`
  48. Player string `json:"player,omitempty"`
  49. }
  50. func (b Board) WriteJSON(w io.Writer, startCol, startRow, cols, rows int) {
  51. fmt.Fprintf(w, "{x=\"%v\",y=\"%v\",rows=\"%v\",columns=\"%v\",tiles={", startCol, startRow, cols, rows)
  52. if startCol > b.Cols {
  53. startCol = b.Cols
  54. }
  55. if startCol < 0 {
  56. cols += startCol
  57. startCol = 0
  58. }
  59. if startRow > b.Rows {
  60. startRow = b.Rows
  61. }
  62. if startRow < 0 {
  63. rows += startRow
  64. startRow = 0
  65. }
  66. log.Printf("startCol: %v", startCol)
  67. if startCol+cols > b.Cols {
  68. cols = b.Cols - startCol
  69. }
  70. log.Printf("startRow: %v", startRow)
  71. if startRow+rows > b.Cols {
  72. rows = b.Cols - startRow
  73. }
  74. if cols < 0 {
  75. cols = 0
  76. }
  77. if rows < 0 {
  78. rows = 0
  79. }
  80. log.Printf("x=%v, y=%v, cols=%v, rows=%v \n", startCol, startRow, cols, rows)
  81. for y := startRow; y < startRow+rows; y++ {
  82. for x := startCol; x < startCol+cols; x++ {
  83. t := &jsonTile{x, y, b.Get(x, y).Name(), ""}
  84. bs, _ := json.Marshal(t)
  85. w.Write(bs)
  86. w.Write([]byte{','})
  87. }
  88. }
  89. fmt.Fprintf(w, "}}")
  90. }
  91. func (b Board) randomizeTile(x, y int) {
  92. switch {
  93. case b.isIglo(x, y):
  94. b.Set(x, y, Iglo)
  95. case b.isRock(x, y):
  96. b.Set(x, y, Rock)
  97. case b.isIce(x, y):
  98. b.Set(x, y, Ice)
  99. default:
  100. b.Set(x, y, Water)
  101. }
  102. }
  103. func (b Board) isIglo(x, y int) bool {
  104. return x == (b.Cols-1) && y == (b.Rows-1)/2
  105. }
  106. func (b Board) isRock(x, y int) bool {
  107. return rand.Intn(10) > 7
  108. }
  109. func (b Board) isIce(x, y int) bool {
  110. leftLimit := (b.Cols - maxIceWidth) / 2
  111. rightLimit := b.Cols/2 + maxIceWidth/2
  112. return x > leftLimit && x < rightLimit && rand.Intn(maxIceWidth) >= abs((b.Cols/2)-x)
  113. }
  114. func abs(a int) int {
  115. if a < 0 {
  116. return -a
  117. }
  118. return a
  119. }