Created
May 18, 2019 21:10
-
-
Save Et7f3/d5013e5721a5519de21e0ecb21c75b78 to your computer and use it in GitHub Desktop.
minesweeper with revery
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
open Revery; | |
open Revery.UI; | |
let () = Random.self_init() | |
module Row = { | |
let component = React.component("Row"); | |
let createElement = (~children, ()) => | |
component(hooks => { | |
let style = | |
Style.[ | |
flexDirection(`Row), | |
justifyContent(`Center), | |
flexGrow(1), | |
]; | |
(hooks, <View style> ...children </View>); | |
}); | |
}; | |
module Column = { | |
let component = React.component("Column"); | |
let createElement = (~children, ()) => | |
component(hooks => { | |
let style = | |
Style.[ | |
flexDirection(`Column), | |
alignItems(`Stretch), | |
justifyContent(`Center), | |
flexGrow(1), | |
]; | |
(hooks, <View style> ...children </View>); | |
}); | |
}; | |
let count_neighbours(matrix, w, h, y, x) = | |
(if (x > 0) | |
((if (y > 0 && matrix[y - 1][x - 1]) 1 else 0) | |
+ (if (matrix[y][x - 1]) 1 else 0) | |
+ (if (y < h && matrix[y + 1][x - 1]) 1 else 0)) | |
else | |
0) | |
+ (if (y > 0 && matrix[y - 1][x]) 1 else 0) | |
+ (if (y < h && matrix[y + 1][x]) 1 else 0) | |
+ (if (x < w) | |
((if (y > 0 && matrix[y - 1][x + 1]) 1 else 0) | |
+ (if (matrix[y][x + 1]) 1 else 0) | |
+ (if (y < h && matrix[y + 1][x + 1]) 1 else 0)) | |
else | |
0) | |
let textStyle = | |
Style.[ | |
color(Colors.black), | |
width(100), | |
fontFamily("Roboto-Regular.ttf"), | |
fontSize(16), | |
margin(14), | |
]; | |
let numbers = [| | |
<Text style=textStyle text="0" />, | |
<Text style=textStyle text="1" />, | |
<Text style=textStyle text="2" />, | |
<Text style=textStyle text="3" />, | |
<Text style=textStyle text="4" />, | |
<Text style=textStyle text="5" />, | |
<Text style=textStyle text="6" />, | |
<Text style=textStyle text="7" />, | |
<Text style=textStyle text="8" />, | |
<Text style=textStyle text="x" />, | |
|]; | |
let minesweeper = (w, h, percent) => { | |
let percent = 101 - percent; | |
let matrix = Array.make_matrix(w, h, false); | |
let (w, h) = (w - 1, h - 1); | |
let matrix = Array.map(Array.map(_ => Random.int(100) >= percent), matrix); /* fill bomb */ | |
let count_neighbours = count_neighbours(matrix, h, w); | |
let make_hint_bomb = (i, j) => numbers[count_neighbours(i, j)]; | |
let make_cell = (i, j) => | |
fun | |
| true => numbers[9] | |
| false => make_hint_bomb(i, j); | |
let make_row = i => Array.mapi(make_cell(i)); | |
let matrix = Array.mapi(make_row, matrix); | |
matrix; | |
}; | |
module MineCell = { | |
type state = { | |
opened : bool, | |
flag : bool, | |
hint : int, | |
} | |
type action = | |
| Open | |
let reducer = (action: action, state) => { | |
switch (action) { | |
| Open => {...state, opened: true} | |
}; | |
}; | |
let initialState = { | |
opened: false, | |
flag: false, | |
hint: 0 | |
}; | |
let component = React.component("MineCell"); | |
let createElement = (~children, ~i, ~j, ~onClick, ()) => | |
component(hooks => { | |
let (state, dispatch, hooks) = Hooks.reducer(~initialState, reducer, hooks); | |
( | |
hooks, <Revery_UI_Components.Clickable onClick={_ => {onClick(i, j); dispatch(Open)}}><View style=Style.[ | |
width(40), | |
height(40), | |
backgroundColor( | |
if (state.opened) | |
Color.rgb(255., 255., 225.) | |
else | |
Color.rgb(0., 0., 0.)), | |
] | |
> ...children </View></Revery_UI_Components.Clickable>, | |
); | |
}); | |
}; | |
type state = { | |
parentBackground: Color.t, | |
}; | |
type action = | |
| SetParentBackground(Color.t) | |
let reducer = (action: action, state) => { | |
switch (action) { | |
| SetParentBackground(c) => {...state, parentBackground: c} | |
}; | |
}; | |
module MineSweeper = { | |
let component = React.component("MineSweeper"); | |
let initialState = { | |
parentBackground: Colors.darkGray, | |
}; | |
let createElement = (~children as _, ()) => { | |
let board = List.map(Array.to_list, Array.to_list(minesweeper(5, 5, 40))); | |
component(hooks => { | |
let (state, dispatch, hooks) = | |
Hooks.reducer(~initialState, reducer, hooks); | |
( | |
hooks, | |
{ | |
let convert_row(i, e) = Row.createElement(~children=List.mapi((j, e) => <MineCell i j onClick={(i, j) => ()}> e </MineCell>, e), ()); | |
Column.createElement(~children=List.mapi((i, e) => convert_row(i, e), board), ()) | |
}, | |
); | |
}); | |
}; | |
}; | |
let render = () => { | |
<View | |
style=Style.[ | |
position(`Absolute), | |
justifyContent(`Center), | |
alignItems(`Center), | |
bottom(0), | |
top(0), | |
left(0), | |
right(0), | |
]> | |
<MineSweeper /> | |
</View>; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
See here for non draft version https://github.com/Et7f3/minesweeper