diff --git a/src/gamepkg/gui.nim b/src/gamepkg/gui.nim index 4037806..ee616d0 100644 --- a/src/gamepkg/gui.nim +++ b/src/gamepkg/gui.nim @@ -7,18 +7,22 @@ from times import getTime, toUnix, nanosecond let now = getTime() randomize(now.toUnix * 1_000_000_000 + now.nanosecond) +const borderWidth = 6 +const boardOffset = 70 + type GameConfig = object rowSize: int boxStride: int borderWidth: float32 sideSize: float32 boardOffset: int + minePercentage: float32 averageMineCount: int proc makeConfig(rowSize: int, borderWidth: float32, boardOffset: int, - minePercentage: float32 = 0.10) : GameConfig = + minePercentage: float32 = 0.05) : GameConfig = let boxStride: int = (950 * (1/rowSize)).int # How much space does a tile take up let sideSize = (boxStride-borderWidth.int).float32 # How long is a side of a tile let averageMineCount = ((rowSize*rowSize).float32 * minePercentage) # How many mines should be placed on average? @@ -28,9 +32,10 @@ proc makeConfig(rowSize: int, borderWidth: borderWidth, sideSize: sideSize, boardOffset: boardOffset, + minePercentage: minePercentage, averageMineCount: averageMineCount.int) -const gameConf = makeConfig(20, 6, 70) +var gameConf: GameConfig # = makeConfig(20, 6, 70) type GameState = enum unfinished, @@ -131,7 +136,7 @@ proc revealBoard(board: Board, tile: Tile) = q.push(neighbour) proc setMine(numMines: int): bool = - let maxR: float = gameConf.rowSize*gameConf.rowSize + let maxR: float = (gameConf.rowSize*gameConf.rowSize).float return rand(max_r) < (numMines.float) proc comparator(a: tuple[l: float32, h: float32], k: int): int = @@ -219,14 +224,13 @@ proc generateBoard(screenWidth: int, screenHeight: int, rowSize: int): Board = state.marked = false state.revealed = false - state.mine = setMine(gameConf.averageMineCount) # average number of mines + state.mine = setMine(gameConf.averageMineCount) state.mineNeighbours = 0 let tile = drawTile(heightPos, widthPos, state) tiles &= @[tile] - # FIXME ugly shit, encapsulate it into a function or make it more terse if xIntervals.len > 0: xIntervals &= @[(l: xIntervals[xIntervals.high].h, h: tile.pos.x.float32)] else: @@ -260,6 +264,9 @@ proc guiLoop*() = echo "gui loop starting" + var minePercentage = 0.10 + var rowSize = 20 + # TODO get from xlib var screenWidth: int = 100 var screenHeight: int = 100 @@ -293,6 +300,7 @@ proc guiLoop*() = SetTargetFPS(60) while not exitWindow and not WindowShouldClose(): + gameConf = makeConfig(rowSize=rowSize, borderWidth=6, boardOffset=70, minePercentage=minePercentage) screenWidth = (monitor.GetMonitorWidth()).int screenHeight = (monitor.GetMonitorHeight()).int mousePos = GetMousePosition() @@ -341,20 +349,42 @@ proc guiLoop*() = exitWindow = GuiWindowBox(Rectangle(x: 0.float32, y: 0.float32, width: screenWidth.float32, height: screenHeight.float32), "#198# Minesweeper".cstring) - restartButton = GuiButton(Rectangle(x: gameConf.boardOffset.float32-10, y: gameConf.boardOffset.float32-20, width: 80.float32, height: 20.float32), "Restart") - - if board.isNone or restartButton: + restartButton = GuiButton(Rectangle(x: gameConf.boardOffset.float32-10, y: gameConf.boardOffset.float32-30, width: 80.float32, height: 20.float32), "Restart") + + minePercentage = GuiSliderBar(Rectangle( + x: gameConf.boardOffset.float32+250, + y: gameConf.boardOffset.float32-30, + width: 80.float32, + height: 20.float32), + "Easier", + "Harder", + minePercentage, + 0.01, 0.50) + + + rowSize = GuiSliderBar(Rectangle( + x: gameConf.boardOffset.float32+650, + y: gameConf.boardOffset.float32-30, + width: 80.float32, + height: 20.float32), + "Smaller", + "Larger", + rowSize.float, + 10, 50).int + + if board.isNone or restartButton or rowSize != gameConf.rowSize or minePercentage != gameConf.minePercentage: # Generate the initial board if there isn't one + gameConf = makeConfig(rowSize=rowSize, borderWidth=borderWidth, boardOffset=boardOffset, minePercentage=minePercentage) board = some(generateBoard(screenWidth, screenHeight, gameConf.rowSize)) gameState = unfinished else: if gameState == won and board.isSome: showBoard(screenWidth, screenHeight, board.get) - DrawText("You won! :)", (screenWidth.float32/2.5).int, (gameConf.boardOffset/2).int, 30, GREEN) + DrawText("You won! :)", (screenWidth.float32/1.5).int, (gameConf.boardOffset).int, 30, GREEN) elif gameState == lost and board.isSome: showBoard(screenWidth, screenHeight, board.get) - DrawText("You lost! :(", (screenWidth.float32/2.5).int, (gameConf.boardOffset/2).int, 30, RED) + DrawText("You lost! :(", (screenWidth.float32/1.5).int, (gameConf.boardOffset).int, 30, RED) # Otherwise update the state of the abstract board with the window else: