Make Minesweeper a bit simpler; WIP

master
Tait Hoyem 4 years ago
parent fa330210b8
commit 31b5cfa827

@ -3,44 +3,85 @@ from channels.generic.websocket import WebsocketConsumer
from asgiref.sync import async_to_sync
from .models import Room, ActiveUser, RPSMove, MinesweeperBoard, MinesweeperCell
from common.models import LameUser
from django.db.models import Q
import random
class MinesweeperConsumer(WebsocketConsumer):
def did_win(self):
def send_client(self, tpy, msg):
self.send(json.dumps({
'type': tpy,
'payload': msg
}))
def hit_bomb(self, sq):
self.send_client('change-board', [{
'x': sq.x,
'y': sq.y,
'flagged': sq.flagged,
'bomb': sq.bomb,
'bombs_next': sq.bombs_next
}])
self.lose()
def client_selected_square(self, x, y):
sq = MinesweeperCell.objects.get(board=self.board, x=x, y=y)
sq.shown = True
sq.save()
if sq.bomb:
self.hit_bomb(sq)
elif sq.bombs_next > 0:
self.send_client('change-board', [{
'x': sq.x,
'y': sq.y,
'flagged': sq.flagged,
'bomb': sq.bomb,
'bombs_next': sq.bombs_next
}])
elif sq.bombs_next == 0:
reved = self.reveal(sq.x, sq.y, [])
# update all the cells to be shwon
# TODO: make faster; this takes noticable time; try for one statement
for tile in reved:
c = MinesweeperCell.objects.get(x=tile['x'], y=tile['y'], board=self.board)
c.shown = True
c.save()
self.send_client('change-board',
reved)
def check_win(self):
if self.has_won():
self.win()
def has_won(self):
shown = list(self.board.cells.filter(shown=True))
not_bombs = list(self.board.cells.filter(bomb=False))
if shown == not_bombs:
self.send(json.dumps({
'type': 'message',
'message': '<b>You win!</b>'
}))
self.board.status = self.board.Status.WON
self.board.save()
return shown == not_bombs
def win(self):
self.send_client('message', '<b>You win!</b>')
self.board.status = self.board.Status.WON
self.board.save()
def send_new_board(self):
self.send(json.dumps({
'type': 'new_board'
}))
self.send(json.dumps({
'type': 'message',
'message': '<i>New board generated!</i>'
}))
self.send_client('new_board', '')
self.send_client('message', '<i>New board generated!</i>')
def flag_tile(self, x, y):
cell = MinesweeperCell.objects.get(x=x, y=y, board=self.board)
cell.flagged = not cell.flagged
cell.save()
def send_shown_flagged(self):
if (self.board.is_game_over()):
self.send(json.dumps({
'type': 'display_full',
'full_board': [x.as_full_dict() for x in self.board.cells.all()]
}))
self.send_client('change-board', [
x.as_full_dict() for x in self.board.cells.all()
])
else:
shown = self.board.cells.filter(shown=True)
# TODO: do not send 'bomb_next' with flagged items
flagged = self.board.cells.filter(flagged=True)
self.send(json.dumps({
'type': 'display',
'partial_board': [x.as_dict() for x in shown],
'flagged': [{'x': x.x, 'y': x.y} for x in flagged]
}))
shown = list(self.board.cells.filter(shown=True))
flagged = list(self.board.cells.filter(flagged=True))
self.send_client('change-board', [
{'x': x.x, 'y': x.y, 'shown': x.shown, 'flagged': x.flagged, 'bombs_next': x.bombs_next} for x in shown+flagged
])
def save_revealed(self, revealed_squares):
# edit database so user can come back later
@ -144,6 +185,11 @@ class MinesweeperConsumer(WebsocketConsumer):
board=self.board,
shown=False
)
def lose(self):
self.send_client('message', '<b>You hit a bomb!</b>')
self.board.status = self.board.Status.LOST
self.board.save()
self.send_shown_flagged()
def connect(self):
self.accept()
@ -161,49 +207,10 @@ class MinesweeperConsumer(WebsocketConsumer):
self.board_generator()
self.send_new_board()
elif data['type'] == 'clicked' and not self.board.is_game_over():
x = data['button_id'] % 10
y = data['button_id'] // 10
# TODO: bomb, 0, other
# TODO: saftey if not exists
cell = MinesweeperCell.objects.get(x=x, y=y, board=self.board)
if cell.bomb:
self.send(json.dumps({
'type': 'message',
'message': '<b>You hit a bomb!</b>'
}))
self.board.status = self.board.Status.LOST
self.board.save()
self.send_shown_flagged()
elif cell.bombs_next == 0:
revealed = self.reveal(x, y, [])
self.send(json.dumps({
'type': 'display',
'partial_board': revealed
}))
self.save_revealed(revealed)
elif cell.bombs_next > 0:
self.send(json.dumps({
'type': 'display',
'partial_board': [
{
'x': x,
'y': y,
'bombs_next': cell.bombs_next
}
]
}))
self.save_revealed([{
'x': x,
'y': y
}])
self.did_win()
self.client_selected_square(data['button_id'] % 10, data['button_id'] // 10)
self.check_win()
elif data['type'] == 'flagged' and not self.board.is_game_over():
x = data['button_id'] % 10
y = data['button_id'] // 10
cell = MinesweeperCell.objects.get(x=x, y=y, board=self.board)
cell.flagged = not cell.flagged
cell.save()
self.did_win()
self.flag_tile(data['button_id'] % 10, data['button_id'] // 10)
class RPSConsumer(WebsocketConsumer):
def group_send(self, message, event='info'):

@ -85,7 +85,7 @@ const send_click = (e, event_type) => {
return;
}
}
console.log(bid)
console.log(bid, event_type);
MSSocket.send(JSON.stringify(
{
'type': event_type,
@ -152,43 +152,34 @@ const global_key_handler = (e) => {
}
};
const change_board = (board_parts) => {
let shown_tiles = 0;
for (cell of board_parts)
{
i = (cell.y*10) + cell.x;
console.log("mscell-" + i)
btn = document.getElementById("mscell-" + i);
if (cell.bomb)
{
make_btn_bomb(btn, BOMB_UNICODE);
} else if (cell.bombs_next >= 0) {
make_btn_bombnum(btn, cell.bombs_next);
} else if (cell.flagged) {
btn_flag(btn, RED_FLAG_UNICODE);
}
shown_tiles++;
}
write_message("You have exposed " + shown_tiles + " tiles");
};
MSSocket.onmessage = (e) => {
console.log(e.data);
console.log(JSON.parse(e.data));
data = JSON.parse(e.data);
if (data.type === 'display') {
let shown_tiles = 0;
for (cell of data.partial_board)
{
i = (cell.y*10) + cell.x;
console.log("mscell-" + i)
btn = document.getElementById("mscell-" + i);
make_btn_bombnum(btn, cell.bombs_next);
shown_tiles++;
}
if (data.flagged)
{
for (cell of data.flagged)
{
i = (cell.y*10) + cell.x;
btn = document.getElementById("mscell-" + i);
btn_flag(btn);
}
}
write_message("You have exposed " + shown_tiles + " tiles");
} else if (data.type === 'display_full') {
for (cell of data.full_board)
{
i = (cell.y*10) + cell.x;
btn = document.getElementById("mscell-" + i);
if (cell.bomb) {
make_btn_bomb(btn);
} else {
make_btn_bombnum(btn, cell.bombs_next);
}
}
if (data.type === 'change-board') {
change_board(data.payload);
} else if (data.type === 'game_over') {
MSSocket.send(JSON.stringify({
'type': 'full_board'
@ -199,7 +190,7 @@ MSSocket.onmessage = (e) => {
btn_clear(btn);
}
} else if (data.type === 'message') {
write_message(data.message);
write_message(data.payload);
}
};

Loading…
Cancel
Save