2018-04-03 15:21:12 -07:00
if not data then
m = 10 ; n = 10 ;
players = { } ;
paused = true
turn = 2 ;
2019-01-27 09:40:29 -08:00
turntimeout = 5
shorttimeout = 1
shortround = false
turnmessage = " "
2018-04-03 15:21:12 -07:00
t = 0 ;
SIGNUP = 0 ; GAME = 1 ; INTERMISSION = 2
state = SIGNUP
t0 = _G.minetest . get_gametime ( ) ; spawnpos = self.spawnpos ( ) -- place mines
data = { } ;
init_game = function ( )
2019-01-27 09:40:29 -08:00
abilitypoints = { 0 , 0 } ; -- points to use ability, step outside ring to use them in following round
shortround = false
2018-04-03 15:21:12 -07:00
data = { } ; minescount = 32
for i = 1 , minescount do local i = math.random ( m ) ; local j = math.random ( n ) ; if not data [ i ] then data [ i ] = { } end ; data [ i ] [ j ] = 1 ; end
if not data [ 1 ] then data [ 1 ] = { } end if not data [ 2 ] then data [ 2 ] = { } end -- create 2x2 safe area
data [ 1 ] [ 1 ] = 0 ; data [ 1 ] [ 2 ] = 0 ; data [ 2 ] [ 1 ] = 0 ; data [ 2 ] [ 2 ] = 0 ;
minescount = 0 ;
for i = 1 , m do for j = 1 , n do -- render game
if data [ i ] and data [ i ] [ j ] == 1 then minescount = minescount + 1 end
if keyboard.read ( { x = spawnpos.x + i , y = spawnpos.y , z = spawnpos.z + j } ) ~= " basic_robot:button808080 " then
keyboard.set ( { x = spawnpos.x + i , y = spawnpos.y , z = spawnpos.z + j } , 2 )
end
end end
keyboard.set ( { x = spawnpos.x + 1 , y = spawnpos.y , z = spawnpos.z + 1 } , 4 ) -- safe start spot
end
get_mine_count = function ( i , j )
if i < 0 or i > m + 1 or j < 0 or j > n + 1 then return 0 end ; count = 0
for k = - 1 , 1 do for l = - 1 , 1 do
if data [ i + k ] and data [ i + k ] [ j + l ] == 1 then count = count + 1 end
end end
return count
end
chk_mines = function ( )
local count = minescount ;
for i = 1 , m do for j = 1 , n do
if keyboard.read ( { x = spawnpos.x + i , y = spawnpos.y , z = spawnpos.z + j } ) == " basic_robot:buttonFF8080 " and data [ i ] and data [ i ] [ j ] == 1 then
count = count - 1
end
end end
return count
end
2019-01-27 09:40:29 -08:00
near_chat = function ( msg )
end
2018-04-03 15:21:12 -07:00
greeting = function ( )
2019-01-27 09:40:29 -08:00
_G.minetest . chat_send_all ( colorize ( " red " ,
" #BATTLE MINESWEEPER : two player battle in minesweeper. say join to play. \n Rules: " ..
" 1. each player has 5 second turn to make a move 2. if you dont make move you lose \n " ..
" 3. if you make move in other player turn you lose. 4. if you hit bomb or mark bomb falsely you lose \n " ..
" 5. by playing fast you get ability charge. when you collect 10 you can step out of ring when your round ends and opponent will only have 2s to play his turn. "
) )
2018-04-03 15:21:12 -07:00
end
player_lost = function ( )
for i = 1 , # players do
local player = _G.minetest . get_player_by_name ( players [ i ] ) ;
if player then player : setpos ( { x = spawnpos.x , y = spawnpos.y + 10 , z = spawnpos.z } ) end
end
2019-01-27 09:40:29 -08:00
_G.minetest . sound_play ( " electric_zap " , { pos = spawnpos , max_hear_distance = 100 } )
2018-04-03 15:21:12 -07:00
state = INTERMISSION ; t = 0
end
function change_turn ( )
2019-01-27 09:40:29 -08:00
shortround = false -- reset ability if activated
2018-04-03 15:21:12 -07:00
if turn == 1 then
_G.minetest . sound_play ( " default_break_glass " , { pos = spawnpos , max_hear_distance = 100 } )
else
2019-01-27 09:40:29 -08:00
_G.minetest . sound_play ( " default_cool_lava " , { pos = spawnpos , max_hear_distance = 100 } )
2018-04-03 15:21:12 -07:00
end
if paused == false then
2019-01-27 09:40:29 -08:00
say ( players [ turn ] .. " lost : didn't make a move fast enough " ) ;
2018-04-03 15:21:12 -07:00
player_lost ( )
else
2019-01-27 09:40:29 -08:00
local player = minetest.get_player_by_name ( players [ turn ] )
local ppos = player : getpos ( )
local x = ppos.x - spawnpos.x ; local y = ppos.y - spawnpos.y ; local z = ppos.z - spawnpos.z ;
local points = abilitypoints [ turn ]
if x < 1 or x > m or z < 1 or z > n then -- outside area
local points = abilitypoints [ turn ]
if points >= 10 then -- do we have enough points?
shortround = true -- next round will be shorter, 2s
_G.minetest . sound_play ( " grinder " , { pos = spawnpos , max_hear_distance = 100 } )
abilitypoints [ turn ] = abilitypoints [ turn ] - 10
end
end
2018-04-03 15:21:12 -07:00
if turn == 1 then turn = 2 else turn = 1 end
2019-01-27 09:40:29 -08:00
turnmessage = " turn " .. turn .. " " .. players [ turn ] .. " ,charge " .. abilitypoints [ turn ] .. " \n "
self.label ( turnmessage )
2018-04-03 15:21:12 -07:00
t = 0
paused = false
end
end
init_game ( )
greeting ( )
self.listen ( 1 )
end
if state == SIGNUP then
speaker , msg = self.listen_msg ( )
if speaker then
if msg == " join " then
players [ # players + 1 ] = speaker ;
local plist = " " ; for i = 1 , # players do plist = plist .. players [ i ] .. " , " end
_G.minetest . chat_send_all ( " BATTLE MINESWEEPER, current players : " .. plist )
if # players >= 2 then
state = GAME
change_turn ( ) ;
keyboard.get ( ) ; t = 0 ;
for i = 1 , # players do
local player = _G.minetest . get_player_by_name ( players [ i ] ) ;
if player then player : setpos ( { x = spawnpos.x , y = spawnpos.y + 1 , z = spawnpos.z } ) end
end
_G.minetest . chat_send_all ( colorize ( " red " , " BATTLE MINESWEEPER " .. m .. " x " .. n .. " with " .. minescount .. " mines. \n " .. players [ turn ] .. " its your move! " ) )
2019-01-27 09:40:29 -08:00
init_game ( )
2018-04-03 15:21:12 -07:00
end
end
end
elseif state == GAME then
t = t + 1 ;
2019-01-27 09:40:29 -08:00
if ( t > turntimeout ) or ( shortround and t > shorttimeout ) then -- change of turn
2018-04-03 15:21:12 -07:00
change_turn ( )
2019-01-27 09:40:29 -08:00
else
self.label ( turnmessage .. " " .. ( turntimeout - t + 1 ) )
2018-04-03 15:21:12 -07:00
end
event = keyboard.get ( ) ;
if event and event.type == 2 and not paused then
if event.puncher == players [ turn ] then
local x = event.x - spawnpos.x ; local y = event.y - spawnpos.y ; local z = event.z - spawnpos.z ;
2019-01-27 09:40:29 -08:00
local points = abilitypoints [ turn ]
if x < 1 or x > m or z < 1 or z > n then -- outside area
2018-04-03 15:21:12 -07:00
else
local ppos = player.getpos ( event.puncher )
2019-01-27 09:40:29 -08:00
points = points + math.max ( turntimeout - t - 2 , 0 ) ; if points > 40 then points = 40 end
abilitypoints [ turn ] = points
2018-04-03 15:21:12 -07:00
if ppos and math.abs ( ppos.x - event.x ) < 0.5 and math.abs ( ppos.z - event.z ) < 0.5 then -- just mark mine
if data [ x ] and data [ x ] [ z ] == 1 then
if keyboard.read ( { x = event.x , y = event.y , z = event.z } ) ~= " basic_robot:button808080 " then
keyboard.set ( { x = event.x , y = event.y , z = event.z } , 2 )
else
keyboard.set ( { x = event.x , y = event.y , z = event.z } , 3 )
end
else
say ( event.puncher .. " lost : marked a bomb where it was none! " ) ;
player_lost ( )
end
else
if data [ x ] and data [ x ] [ z ] == 1 then
_G.minetest . sound_play ( " tnt_boom " , { pos = spawnpos , max_hear_distance = 100 } )
keyboard.set ( { x = spawnpos.x + x , y = spawnpos.y , z = spawnpos.z + z } , 3 )
say ( event.puncher .. " lost : punched a bomb! " ) ;
player_lost ( )
else
local count = get_mine_count ( x , z ) ;
if count == 0 then keyboard.set ( { x = spawnpos.x + x , y = spawnpos.y , z = spawnpos.z + z } , 4 )
else keyboard.set ( { x = spawnpos.x + x , y = spawnpos.y , z = spawnpos.z + z } , 7 + count ) end
end
end
end
paused = true
else
say ( event.puncher .. " lost : played out of his/her turn " ) ; player_lost ( )
end
end
elseif state == INTERMISSION then
2019-01-27 09:40:29 -08:00
t = t + 1 ; if t > 15 then state = SIGNUP ; players = { } ; paused = true ; greeting ( ) end
2018-04-03 15:21:12 -07:00
end