Logo Interactive Map Based Game.

Version 1 HTML mediated

Version 2 Logo mediated

Version 1 using HTML maps

This is a game which uses maps, graphics and a database. The GUI (Graphical User Interface) is written in HTML and PHP. The GUI is styled with CSS sheets. Most of the HTML code is generated by LOGO. The database element is written in LOGO though it might be upgraded to MySQL.

The program contains several elements.

  1. startgame This sets the board up and gives the players' units random start positions. One player only runs this program at the start.
  2. background. This generates the background map and grid.
  3. player1map etc. This draws the units belonging to player 1 etc.
  4. mapwriter This writes the map information to an HTML file called map.htm.
  5. combat sorts out combats when units enter the same square.
  6. makemap draws the map right at the start.
  7. mapdraw pulls all the map drawing bits together.
  8. reinforce adds reinforcements to existing units.
  9. readmap reads the map from the textfile.
  10. writemap writes the map to the textfile.

To play the game:

  1. Create a network folder called logogame on the drive which matches the drive name in the program. (W: in Whitehaven School. If need be change this by using Notepad in seek and destroy mode.)
  2. One player then runs startgame.
  3. Each player then uses move1 etc. to move their units.
  4. Keep clicking refresh to see changes to the map.

makemap

This creates the game. It writes the game information to a text file called "E:\\logogame\\mygame\\board.txt
Make sure that you are writing to a extant directory! The easiest way to change the directory code is to open the whole blogwrit.lgo file in notepad and use find/replace in seek and destroy mode. (ie substitute W: for D:)

This file is a primitive database. In the current form of the game it contains 200 numbers. 0-99 belong to player 1. 100-199 belong to player 2. The board is a 10x10 grid.
All of the squares are empty except the two homebases of the players which are given value 5 and placed at random in the top and bottom halves of the board.

to makemap
make "board (array 200 0)
repeat 100 [ setitem repcount-1 :board 0]
repeat 100 [ setitem repcount-1+100 :board 1]
setitem random 50 :board 5
setitem (140+random 50) :board 5
openwrite "E:\\logogame\\mygame\\board.txt
setwrite "E:\\logogame\\mygame\\board.txt
repeat 200 [print item repcount-1 :board]
setwrite[]
close "E:\\logogame\\mygame\\board.txt
end

startgame

This calls all the programs needed to get the game going.

to startgame
make "turns 0
makemap
background
mapdraw
end

background

This generates a table and fills it with numbered spaces. This is the bottom layer of the board. You could insert images at this point if you wanted to. The other layers above this will overwrite anything in this layer.

to background
make "map0 "<table>
repeat 10
make "y repcount-1 make "map0 (se :map0 "<tr>)
repeat 10 [
make "x repcount-1 make "num :y*10+:x make "map0 (se :map0 "<td>)
make "map0 (se :map0 "<p> :num "</p>)
make "map0 (se :map0 "</td>) ]
make "map0 (se :map0 "</tr>) ]
make "map0 (se :map0 "<tr><td "colspan=\"10\">)
make "map0 (se :map0 "<p>Turn "number "</p> "<p> :turns "</p></td></tr>)
make "map0 (se :map0 "</table>)
end

mapdraw

This calls the map drawing and mapwriting programs in the right order with the right arguments.

to mapdraw
make "turns :turns+1
if (remainder :turns 3)=0 [reinforce]
combat
readmap
background player1map
player2map
pl1mapfor2
pl2mapfor1
mapwriter :map0 :map1 :map2
mapwriter1 :map0 :map1 :map2f1
mapwriter2 :map0 :map1f2 :map2
end

player1map

This draws the board from the point of view of player n. It draws a table and inserts the number of units in that box of the table. Images of the units could be used instead etc.

to player1map
make "map1 "<table>
repeat 10 [
make "y repcount-1
make "map1 (se :map1 "<tr>)
repeat 10 [
make "x repcount-1
make "map1 (se :map1 "<td>)
make "value item :y*10+:x :board
ifelse :value=0 [
make "map1 (se :map1 "&nbsp\;)][
make "map1 (se :map1 :value)]
make "map1 (se :map1 :value)
make "map1 (se :map1 "</td>) ]
make "map1 (se :map1 "</tr>) ]
make "map1 (se :map1 "</table>)
end

player1map exists in 4 forms:

player1map draws :map1 which shows number values of player1's troops for player1.

player2map draws :map2 which shows number values of player2's troops for player2.

pl1mapfor2 draws :map1f2 which shows a symbol for player1's troops for player2.

pl2mapfor1 draws :map2f1 which shows a symbol for player2's troops for player1.

mapwriter :map0 :map1 :map2

This assembles the background and the player maps into one HTML file. It includes the call to the CSS file which styles the page.

to mapwriter :text1 :text2 :text3
openwrite "E:\\logogame\\mygame\\map.htm
setwrite "E:\\logogame\\mygame\\map.htm
print [<HTML>]
print [<HEAD>]
print [<link href=\"table.css\" rel=\"stylesheet\" type=\"text/css\">]
print [</HEAD>]
print [<BODY>]
print [<div class="layer1">]
print :text1
print [</div>]
print [<div class="layer2">]
print :text2
print [</div>]
print [<div class="layer3">]
print :text3
print [</div>]
print [</BODY>]
print [</HTML>]
setwrite[]
close "E:\\logogame\\mygame\\map.htm
end

mapwriter exists in three forms.

mapwriter :map0 :map1 :map2
This produces the file map.htm which is the referee's copy of the map

mapwriter1 :map0 :map1 :map2f1
This produces the file map1.htm which is player1's copy of the map

mapwriter2 :map0 :map1f2 :map2
This produces the file map2.htm which is player2's copy of the map

move1

This moves some of player1's units from one square to another. 1 unit must always be left in the original square. If too many units are moved then an alert box is triggered.
The relevant map is redrawn at the end of the move.

to move1 :fromsquare :units :tosquare
readmap
make "unitsav item :fromsquare :board
ifelse :units<:unitsav [
setitem :fromsquare :board :unitsav-:units
make "newunits item :tosquare :board
setitem :fromsquare :board :unitsav-:units
setitem :tosquare :board :units+:newunits
][
messagebox [ALERT!!][You haven't enough units in that square. ]]
writemap
mapdraw
end

move2 moves player2's units.

Download the code.

If you already have LOGO running then this link might autorun the code. The best bet is probably to right click this link, save the code and then play with it in the normal way. You could run it through Notepad2 first to do the directory changes as needed.

mygame.lgoThis is the two player version described on this page.

multplay.lgoThis is a five player version which has extra procedures to allow players to get PINs etc..

Make the stylesheet.

Cut and paste the code below into a Notepad2 file and save it as table.css in the working directory for the maps.

table { border-collapse: collapse; width: 600px; }
td { vertical-align:top; width: 10%; height: 40px;}
.layer1 table { z-index:1; font-size:12pt; color:green; position:absolute;
left:0px; top:0px; border: 2px solid red}
.layer1
td {border: 2px solid red; }
.layer2 table {z-index:2; font-size:16pt; color:red;
position:absolute; left:15px; top:25px}
.layer3 table {z-index:3; font-size:12pt; color:blue;
position:absolute; left:25px; top:15px; }

Reinforcements

This routine adds one unit to all none empty squares.

to reinforce
readmap
repeat 10 [
make "y repcount-1
repeat 10 [
make "x repcount-1
make "value item :y*10+:x :board
if :value>0 [ setitem :y*10+:x :board :value+1]
make "value item :y*10+:x+100 :board
if :value>0 [ setitem :y*10+:x+100 :board :value+1]
] ]
writemap
end

Combat

This procedure finds all the squares with contesting armies in them and resolves combat. This system rolls a three sided dice for each player and adds it to the number of units they have in the square. The difference in totals is then subtracted.

to combat
readmap
repeat 10 [
make "y repcount-1
repeat 10 [
make "x repcount-1
make "value1 item :y*10+:x :board
make "value2 item :y*10+:x+100 :board
if :value1>0 [
if :value2>0 [
make "roll1 :value1+random 3
make "roll2 :value2+random 3
if :roll1>:roll2 [
ifelse (:value2-:roll1+:roll2)>0 [
setitem :y*10+:x+100 :board :value2-:roll1+:roll2 ][
setitem :y*10+:x+100 :board 0]]
if :roll2>:roll1 [
ifelse (:value1-:roll2+:roll1)>0 [
setitem :y*10+:x :board :value1-:roll2+:roll1 ][
setitem :y*10+:x :board 0]]
if :roll2=:roll1 [
setitem :y*10+:x+100 :board :value2-1
setitem :y*10+:x :board :value1-1 ]
]]
]]
writemap
end

readmap

Reads the :board array from the text file.

to readmap
openread "E:\\logogame\\mygame\\board.txt
setread "E:\\logogame\\mygame\\board.txt
repeat 200 [setitem repcount-1 :board first readlist ]
close "E:\\logogame\\mygame\\board.txt
end

writemap

Writes the :board array to a text file.

to writemap
openwrite "E:\\logogame\\mygame\\board.txt
setwrite "E:\\logogame\\mygame\\board.txt
repeat 200 [print item repcount-1 :board]
setwrite[]
close "E:\\logogame\\mygame\\board.txt
end

Screenshots


Referee's view.

Player1's view.

Player2's view.

Version 2 using Logo maps

Simplified version which runs within Logo but still uses a central set of text files for the map and player IDs. All graphics are drawn direct to the Logo screen.

The program contains several elements.

  1. startgame: This sets the board up and gives the players' units random start positions. One player only runs this program at the start.
  2. login: this generates the players individual playernumber.
  3. background: This generates the background map and grid.
  4. makemap draws the map right at the start.
  5. readmap reads the map from the textfile.
  6. writemap writes the map to the textfile.
  7. playermap: This draws the units belonging to the player and adds the symbol for each of the other players units.
  8. reinforce adds reinforcements to existing units.
  9. combat: sorts out combats when units enter the same square.
  10. move: this allows a player to move their units.
  11. mapdraw: summons the necessary procedures in the right order after a move command.

To play the game:

  1. Create a network folder called logogame on the drive which matches the drive name in the program. (W: in Whitehaven School. If need be change this by using Notepad in seek and destroy mode.)
  2. One player then runs startgame.
  3. Each player then runs login.
  4. Each player then issues move commands to their units.

makemap

This creates the game. It writes the game information to a text file called "W:\\logogame\\mygame\\board.txt
Make sure that you are writing to a extant directory! The easiest way to change the directory code is to open the whole blogwrit.lgo file in notepad and use find/replace in seek and destroy mode. (ie substitute W: for D:)

This file is a primitive database. In the current form of the game it contains 500 numbers. 0-99 belong to player 1. 100-199 belong to player 2 and so on. The board is a 10x10 grid.
All of the squares are empty except the homebases of the players which are given value 5 and placed at random on the board.

to makemap :players
make "mpboard (array 100*:players 0)
for [n 0 :players-1 1] [
repeat 100 [ setitem 100*:n+repcount-1 :mpboard 0]
setitem (5+random 90)+100*:n :mpboard 5
]
openwrite "W:\\logogame\\mygame\\mpboard.txt
setwrite "W:\\logogame\\mygame\\mpboard.txt
repeat 100*:players [print item repcount-1 :mpboard]
setwrite[]
close "W:\\logogame\\mygame\\mpboard.txt
end

startgame

This calls all the programs needed to get the game going.

to startgame
make "turns 0
makemap
background
mapdraw
end

To run startgame type: startgame 5 (for 5 players)

background

This generates a table and fills it with numbered spaces. This is the bottom layer of the board. You could insert images at this point if you wanted to. The other layers above this will overwrite anything in this layer unless you use transparent gifs drawn using The GIMP etc..

to background
cs ht
setpencolor (list 0 0 0 )
repeat 10 [
make "y repcount-1
repeat 10 [
make "x repcount-1
pu home
setxy :x*80-400 :y*(-50)+200
make "num :y*10+:x
pd repeat 2 [rt 90 fd 80 rt 90 fd 50]
back 25 rt 90
label :num
] ]
end

mapdraw

This reads the map and checks to see if it is time for reinforcements. Then it checks to see if combats have ocurred before redrawing the map file and player's map.

to mapdraw :players
readmap :players
make "turns :turns+1
if (remainder :turns 3)=0 [reinforce :players]
combat :players
readmap :players
background
playermap :players
end

playermap

This draws the board from the point of view of player n. It draws uses background's table and inserts the number of units in that box of the table. Images of the units could be used instead etc.

to playermap :players
repeat :players [
make "mapnum repcount
repeat 10 [
make "y repcount-1
repeat 10 [
make "x repcount-1
repeat :players [
make "value item :y*10+:x+100*(repcount-1) :mpboard
ifelse :value=0 [
][
pu home
setxy :x*80-400 :y*(-50)+200
back 10 rt 90 fd 30
pd
ifelse repcount=:mapnum[
setpencolor (list 20 255 100)
label :value
][
setpencolor (list 255 0 0)
label repcount
]]]]]]
end

login

to login
openread "W:\\logogame\\mygame\\logon.txt
setread "W:\\logogame\\mygame\\logon.txt
make "playnum first readlist
close "W:\\logogame\\mygame\\logon.txt
openwrite "W:\\logogame\\mygame\\logon.txt
setwrite "W:\\logogame\\mygame\\logon.txt
print :playnum-1
setwrite[]
close "W:\\logogame\\mygame\\logon.txt
messagebox (se "YOU "ARE "PLAYER :playnum)[]
end

To run login type: login

Combat

This procedure finds all the squares with contesting armies in them and resolves combat. This system rolls a three sided dice for each player and adds it to the number of units they have in the square. The difference in totals is then subtracted.

to combat :players
readmap :players
repeat 10 [
make "y repcount-1
repeat 10 [
make "x repcount-1
make "rollmax 0
make "sqoccs 0
repeat :players [
if (item :y*10+:x+100*(repcount-1) :mpboard)>0 [ make "sqoccs :sqoccs+1]]
if (:sqoccs>1) [
repeat :players [
make "rollname (word "roll repcount)
make :rollname item :y*10+:x+100*(repcount-1) :mpboard
make :rollname (thing :rollname)+random 6
if :rollmax<(thing :rollname)[ make "rollmax thing :rollname] ]
repeat :players [
make "rollname (word "roll repcount)
ifelse :rollmax=(thing :rollname)[ ] [
make "value item :y*10+:x+100*(repcount-1) :mpboard
make "value :value-(:rollmax-(thing :rollname))
if :value<0 [ make "value 0]
setitem :y*10+:x+100*(repcount-1) :mpboard :value ]
]]
]]
writemap :players
end

move

This moves some of the player's units from one square to another. 1 unit must always be left in the original square. If too many units are moved then an alert box is triggered.
The relevant map is redrawn at the end of the move.

to move1 :fromsquare :units :tosquare
readmap
make "unitsav item :fromsquare :board
ifelse :units<:unitsav [
setitem :fromsquare :board :unitsav-:units
make "newunits item :tosquare :board
setitem :fromsquare :board :unitsav-:units
setitem :tosquare :board :units+:newunits
][
messagebox [ALERT!!][You haven't enough units in that square. ]]
writemap
mapdraw
end

To use move type: move START UNITS FINISH you must always leave one unit behind.
for example move 23 4 56 moves 4 units

Reinforcements

This routine adds one unit to all none empty squares.

to reinforce
readmap
repeat 10 [
make "y repcount-1
repeat 10 [
make "x repcount-1
make "value item :y*10+:x :board
if :value>0 [ setitem :y*10+:x :board :value+1]
make "value item :y*10+:x+100 :board
if :value>0 [ setitem :y*10+:x+100 :board :value+1]
] ]
writemap
end

readmap

Reads the :board array from the text file.

to readmap
openread "W:\\logogame\\mygame\\board.txt
setread "W:\\logogame\\mygame\\board.txt
repeat 500 [setitem repcount-1 :board first readlist ]
close "W:\\logogame\\mygame\\board.txt
end

writemap

Writes the :board array to a text file.

to writemap
openwrite "W:\\logogame\\mygame\\board.txt
setwrite "W:\\logogame\\mygame\\board.txt
repeat 500 [print item repcount-1 :board]
setwrite[]
close "W:\\logogame\\mygame\\board.txt
end

Screenshots


Last updated 24th February 2010