diff options
-rw-r--r-- | data.js | 2 | ||||
-rw-r--r-- | play.html | 2 | ||||
-rw-r--r-- | play.js | 24 | ||||
-rw-r--r-- | rules.js | 255 | ||||
-rw-r--r-- | tools/gendata.js | 31 |
5 files changed, 271 insertions, 43 deletions
@@ -4,5 +4,5 @@ const side_road = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,0,4,4,0,0,4,0,4,0 const side_limit = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,1,0,0,1,0,1,0,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,2,1,0,1,1,0,0,0,0,0,0,0,1,2,2,2,1,1,0,1,2,2,2,2,2,2,2,0,0,1,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,2,1,0,2,1,0,0,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,0,1,2,0,0,2,0,2,2,0,0,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,2,0,0,0,0,0,0,0,0,0,1,2,0,2,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,0,0,0,0,0,0,0,0,0,0,0,0,2,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,0,2,0,1,0,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,2,2,2,2,2,2,2,0,0,2,0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] const hex_name = {"7":"El Garib","8":"Cyrene","9":"El Gubba","10":"Derna","30":"Tocra","31":"Barce","32":"Marawa","33":"Wadi Cuff","34":"Wadi Cuff E","35":"Gazala","36":"Acroma","37":"Tobruk","38":"Belhamed","39":"Gambut","40":"Bardia","54":"Benghazi","55":"Er Regima","56":"Charruba","57":"Charruba E","58":"Mechili","59":"Rotonda Segnali","60":"Sidi Mufta","61":"Bir Harmat","62":"El Adem","63":"Sidi Rezegh","64":"Ft. Capuzzo","65":"Sollum","66":"Buq Buq","67":"Sidi Barrani","68":"Sidi Barrani E","69":"Mersa Matruh","70":"Fuka","71":"El Daba","72":"El Alamein","73":"El Hamam","74":"Alexandria","78":"Ghemines","79":"Skeleidima","80":"Msus","81":"Msus E","82":"Tengeder W","83":"Tengeder","84":"Tengeder E","85":"Bir Hacheim","86":"Retma","87":"Bir Gubi","88":"Gabr Saleh","89":"Sidi Omar","90":"Bir Habata","91":"Sofafi","92":"Sofafi E","93":"Bir el Kenayis","94":"Bir Khalda","95":"Bir Khalda E","96":"Alam Halfa W","97":"Alam Halfa","98":"Alam Halfa E","103":"Beda Fomm","104":"Antelat","105":"Antelat E","106":"Ben Gania","107":"Ben Gania E","108":"Tengeder SE","109":"Bir Hacheim SW","110":"Bir Hacheim SE","111":"Retma SE","112":"Ft. Maddalena W","113":"Ft. Maddalena","114":"Ft. Maddalena E","115":"Bir Khamsa","116":"Bir el Qatrani","117":"Bir el Qatrani E","118":"Bir el Kenayis SE","119":"Bir Khalda SE","120":"El Himeimat W","121":"El Himeimat","122":"El Himeimat E","128":"Agedabia","129":"Jebel el Matar","130":"Haraga","131":"Haraga E","137":"Ft. Maddalena SW","138":"Ft. Maddalena SE","139":"Bir Khamsa SW","140":"Bir Fuad W","141":"Bir Fuad","142":"Bir Fuad E","151":"El Agheila","152":"Mersa Brega","153":"El Haseiat","154":"El Haseiat E","155":"Haraga SE","162":"Jarabub Oasis NW","163":"Jarabub Oasis NE","165":"Bir Fuad SW","166":"Bir Fuad SE","176":"Maaten Giofer","177":"Maaten Giofer E","178":"Sahaba","179":"Sahaba E","180":"Jalo Oasis NE","186":"Jarabub Oasis W","187":"Jarabub Oasis","188":"Jarabub Oasis E","189":"Siwa Oasis NE","200":"Maaten Giofer SW","201":"Maaten Giofer SE","202":"Sahaba SW","203":"Jalo Oasis W","204":"Jalo Oasis","205":"Jalo Oasis E","211":"Jarabub Oasis SW","212":"Siwa Oasis W","213":"Siwa Oasis","214":"Siwa Oasis E"} const regions = {"Libya":[7,8,9,10,30,31,32,33,34,35,36,37,38,39,40,54,55,56,57,58,59,60,61,62,63,64,78,79,80,81,82,83,84,85,86,87,88,103,104,105,106,107,108,109,110,111,112,113,128,129,130,131,132,133,134,135,136,137,138,151,152,153,154,155,156,157,158,159,160,161,162,176,177,178,179,180,181,182,183,184,185,186,187,200,201,202,203,204,205,206,207,208,209,210,211],"Egypt":[65,66,67,68,69,70,71,72,73,74,89,90,91,92,93,94,95,96,97,98,114,115,116,117,118,119,120,121,122,123,139,140,141,142,143,144,163,164,165,166,167,188,189,190,191,212,213,214,215],"Sidi Omar":[89],"Tobruk":[37],"Sollum":[65],"El Agheila":[151],"Mersa Brega":[152],"East Line":[36,37,38,39,40,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,85,86,87,88,89,90,91,92,93,94,95,96,97,98,112,113,114,115,116,117,118,119,120,121,122,123,137,138,139,140,141,142,143,144,162,163,164,165,166,167,187,188,189,190,191],"West Line":[7,8,9,10,30,31,32,33,34,35,54,55,56,57,58,59,78,79,80,81,82,83,103,104,105,106,107,128,129,130],"Jebel el Akhdar":[7,8,9,32,33,34,56,57],"Sebkha el Segira":[152,176],"Sebket el Jeneinen":[179,203],"Qattara Depression":[144,145,146,168,169,192,193,216,217]} -const units = [{"nationality":"italian","type":"infantry","class":"infantry","speed":1,"appearance":"S","steps":4,"elite":0,"label":12,"name":"Tre"},{"nationality":"italian","type":"infantry","class":"infantry","speed":1,"appearance":"S","steps":4,"elite":0,"label":13,"name":"Pav"},{"nationality":"italian","type":"infantry","class":"infantry","speed":1,"appearance":"S","steps":4,"elite":0,"label":14,"name":"Bre"},{"nationality":"italian","type":"infantry","class":"infantry","speed":1,"appearance":"S","steps":3,"elite":0,"label":15,"name":"Bol"},{"nationality":"italian","type":"infantry","class":"infantry","speed":1,"appearance":"S","steps":3,"elite":0,"label":16,"name":"Sav"},{"nationality":"italian","type":"mech. inf.","class":"infantry","speed":3,"appearance":7,"steps":4,"elite":0,"label":21,"name":"Tri"},{"nationality":"italian","type":"infantry","class":"infantry","speed":1,"appearance":7,"steps":2,"elite":0,"label":22,"name":"Sab"},{"nationality":"italian","type":"armor","class":"armor","speed":3,"appearance":11,"steps":3,"elite":0,"label":23,"name":"Lit"},{"nationality":"italian","type":"mot. inf.","class":"infantry","speed":2,"appearance":17,"steps":3,"elite":0,"label":24,"name":"Fas"},{"nationality":"italian","type":"mot. inf.","class":"infantry","speed":2,"appearance":19,"steps":3,"elite":0,"label":25,"name":"Cen"},{"nationality":"italian","type":"infantry","class":"infantry","speed":1,"appearance":19,"steps":2,"elite":0,"label":26,"name":"Pis"},{"nationality":"italian","type":"para","class":"infantry","speed":1,"appearance":"M","steps":4,"elite":0,"label":27,"name":"Fol"},{"nationality":"italian","type":"artillery","class":"artillery","speed":1,"appearance":"S","steps":2,"elite":0,"label":28,"name":"Ita"},{"nationality":"italian","type":"armor","class":"armor","speed":3,"appearance":"S","steps":4,"elite":0,"label":29,"name":"Ari"},{"nationality":"german","type":"armor","class":"armor","speed":3,"appearance":"S","steps":3,"elite":1,"label":14,"name":"21/5"},{"nationality":"german","type":"recon","class":"armor","speed":4,"appearance":"S","steps":1,"elite":1,"label":15,"name":"21/3"},{"nationality":"german","type":"mech. inf.","class":"infantry","speed":3,"appearance":"S","steps":3,"elite":1,"label":16,"name":"21/104"},{"nationality":"german","type":"recon","class":"armor","speed":4,"appearance":3,"steps":1,"elite":1,"label":17,"name":"15/33"},{"nationality":"german","type":"mob. a/t","class":"antitank","speed":3,"appearance":3,"steps":2,"elite":1,"label":18,"name":"88mm/A"},{"nationality":"german","type":"mech. inf.","class":"infantry","speed":3,"appearance":3,"steps":3,"elite":1,"label":19,"name":"15/115"},{"nationality":"german","type":"armor","class":"armor","speed":3,"appearance":5,"steps":3,"elite":1,"label":21,"name":"15/8"},{"nationality":"german","type":"recon","class":"armor","speed":4,"appearance":5,"steps":1,"elite":1,"label":22,"name":"90/580"},{"nationality":"german","type":"mot. inf.","class":"infantry","speed":2,"appearance":5,"steps":2,"elite":1,"label":23,"name":"90/361"},{"nationality":"german","type":"mot. a/t","class":"antitank","speed":2,"appearance":5,"steps":2,"elite":1,"label":24,"name":"50mm"},{"nationality":"german","type":"artillery","class":"artillery","speed":1,"appearance":7,"steps":2,"elite":1,"label":25,"name":"/104"},{"nationality":"german","type":"mot. inf.","class":"infantry","speed":2,"appearance":7,"steps":2,"elite":1,"label":26,"name":"90/200"},{"nationality":"german","type":"mob. a/t","class":"antitank","speed":3,"appearance":11,"steps":2,"elite":1,"label":27,"name":"88mm/B"},{"nationality":"german","type":"mech. inf.","class":"infantry","speed":3,"appearance":11,"steps":2,"elite":1,"label":28,"name":"90/sv288"},{"nationality":"german","type":"mech. inf.","class":"infantry","speed":3,"appearance":11,"steps":2,"elite":1,"label":29,"name":"90/346"},{"nationality":"german","type":"para","class":"infantry","speed":1,"appearance":"M","steps":3,"elite":1,"label":31,"name":"Ram"},{"nationality":"german","type":"infantry","class":"infantry","speed":1,"appearance":"M","steps":3,"elite":1,"label":32,"name":"164/382+433"},{"nationality":"german","type":"infantry","class":"infantry","speed":1,"appearance":"M","steps":2,"elite":1,"label":33,"name":"164/125"},{"nationality":"german","type":"mech. inf.","class":"infantry","speed":3,"appearance":3,"steps":3,"elite":1,"label":34,"name":"90/155"},{"nationality":"german","type":"mot. a/t","class":"antitank","speed":2,"appearance":17,"steps":2,"elite":1,"label":35,"name":"76mm"},{"nationality":"allied","type":"armor","class":"armor","speed":3,"appearance":"S","steps":2,"elite":0,"label":14,"name":"2/3"},{"nationality":"allied","type":"mech. inf.","class":"infantry","speed":3,"appearance":"S","steps":2,"elite":0,"label":15,"name":"2/SG"},{"nationality":"allied","type":"mech. inf.","class":"infantry","speed":3,"appearance":"S","steps":2,"elite":0,"label":16,"name":"4IN/3m"},{"nationality":"allied","type":"mot. inf.","class":"infantry","speed":2,"appearance":"S","steps":4,"elite":0,"label":17,"name":"9AU/20"},{"nationality":"allied","type":"mot. inf.","class":"infantry","speed":2,"appearance":"S","steps":4,"elite":0,"label":18,"name":"70/14+16"},{"nationality":"allied","type":"mot. inf.","class":"infantry","speed":2,"appearance":"S","steps":3,"elite":0,"label":19,"name":"70/23"},{"nationality":"allied","type":"armor","class":"armor","speed":3,"appearance":"T","steps":1,"elite":1,"label":21,"name":"Matilda/A"},{"nationality":"allied","type":"mech. inf.","class":"infantry","speed":3,"appearance":"T","steps":3,"elite":0,"label":22,"name":"7/SG"},{"nationality":"allied","type":"mech. inf.","class":"infantry","speed":3,"appearance":"T","steps":3,"elite":0,"label":23,"name":"7/22G"},{"nationality":"allied","type":"mot. inf.","class":"infantry","speed":2,"appearance":"T","steps":3,"elite":0,"label":24,"name":"/Pol"},{"nationality":"allied","type":"mot. inf.","class":"infantry","speed":2,"appearance":"T","steps":3,"elite":0,"label":25,"name":"7AU/18"},{"nationality":"allied","type":"artillery","class":"artillery","speed":1,"appearance":"T","steps":2,"elite":0,"label":26,"name":"/Tob"},{"nationality":"allied","type":"mot. inf.","class":"infantry","speed":2,"appearance":18,"steps":4,"elite":0,"label":27,"name":"51H/152"},{"nationality":"allied","type":"self prop. arty","class":"artillery","speed":3,"appearance":18,"steps":2,"elite":0,"label":28,"name":"Priest"},{"nationality":"allied","type":"artillery","class":"artillery","speed":1,"appearance":18,"steps":4,"elite":0,"label":29,"name":"/C"},{"nationality":"allied","type":"armor","class":"armor","speed":3,"appearance":2,"steps":4,"elite":0,"label":31,"name":"7/7"},{"nationality":"allied","type":"mech. inf.","class":"infantry","speed":3,"appearance":2,"steps":3,"elite":0,"label":32,"name":"4IN/7m"},{"nationality":"allied","type":"mot. inf.","class":"infantry","speed":2,"appearance":2,"steps":3,"elite":0,"label":33,"name":"4IN/5"},{"nationality":"allied","type":"mot. inf.","class":"infantry","speed":2,"appearance":2,"steps":3,"elite":0,"label":34,"name":"4IN/11"},{"nationality":"allied","type":"armor","class":"armor","speed":3,"appearance":4,"steps":1,"elite":1,"label":35,"name":"Matilda/B"},{"nationality":"allied","type":"i-tank","class":"armor","speed":3,"appearance":4,"steps":4,"elite":0,"label":36,"name":"/1AT"},{"nationality":"allied","type":"armor","class":"armor","speed":3,"appearance":4,"steps":3,"elite":0,"label":37,"name":"7/4"},{"nationality":"allied","type":"recon","class":"armor","speed":4,"appearance":4,"steps":2,"elite":0,"label":38,"name":"7"},{"nationality":"allied","type":"artillery","class":"artillery","speed":1,"appearance":20,"steps":3,"elite":0,"label":39,"name":"/D"},{"nationality":"allied","type":"mot. a/t","class":"antitank","speed":2,"appearance":6,"steps":3,"elite":0,"label":41,"name":"2#"},{"nationality":"allied","type":"mech. inf.","class":"infantry","speed":3,"appearance":6,"steps":4,"elite":0,"label":42,"name":"2NZ/4"},{"nationality":"allied","type":"mech. inf.","class":"infantry","speed":3,"appearance":6,"steps":4,"elite":0,"label":43,"name":"2NZ/5"},{"nationality":"allied","type":"mech. inf.","class":"infantry","speed":3,"appearance":6,"steps":4,"elite":0,"label":44,"name":"2NZ/6"},{"nationality":"allied","type":"mot. inf.","class":"infantry","speed":2,"appearance":6,"steps":4,"elite":0,"label":45,"name":"1SA/2+5"},{"nationality":"allied","type":"mot. inf.","class":"infantry","speed":2,"appearance":6,"steps":3,"elite":0,"label":46,"name":"1SA/1"},{"nationality":"allied","type":"recon","class":"armor","speed":4,"appearance":8,"steps":2,"elite":0,"label":47,"name":"1SA"},{"nationality":"allied","type":"mot. inf.","class":"infantry","speed":2,"appearance":8,"steps":3,"elite":0,"label":48,"name":"1SA/3"},{"nationality":"allied","type":"mot. inf.","class":"infantry","speed":2,"appearance":8,"steps":3,"elite":0,"label":49,"name":"2SA/4+6"},{"nationality":"allied","type":"armor","class":"armor","speed":3,"appearance":8,"steps":4,"elite":0,"label":51,"name":"1/22"},{"nationality":"allied","type":"i-tank","class":"armor","speed":3,"appearance":8,"steps":3,"elite":0,"label":52,"name":"/32AT"},{"nationality":"allied","type":"artillery","class":"artillery","speed":1,"appearance":8,"steps":2,"elite":0,"label":53,"name":"/A"},{"nationality":"allied","type":"armor","class":"armor","speed":3,"appearance":10,"steps":4,"elite":0,"label":54,"name":"1/2"},{"nationality":"allied","type":"mech. inf.","class":"infantry","speed":3,"appearance":10,"steps":3,"elite":0,"label":55,"name":"1/201G"},{"nationality":"allied","type":"mech. inf.","class":"infantry","speed":3,"appearance":10,"steps":2,"elite":0,"label":56,"name":"1/SG"},{"nationality":"allied","type":"mot. inf.","class":"infantry","speed":2,"appearance":10,"steps":3,"elite":0,"label":57,"name":"5IN/29"},{"nationality":"allied","type":"armor","class":"armor","speed":3,"appearance":12,"steps":2,"elite":1,"label":58,"name":"Grant"},{"nationality":"allied","type":"mot. a/t","class":"antitank","speed":2,"appearance":12,"steps":3,"elite":0,"label":59,"name":"6#/A"},{"nationality":"allied","type":"mech. inf.","class":"infantry","speed":3,"appearance":14,"steps":2,"elite":0,"label":61,"name":"10IN/161m"},{"nationality":"allied","type":"mot. inf.","class":"infantry","speed":2,"appearance":14,"steps":4,"elite":0,"label":62,"name":"5IN/9+10"},{"nationality":"allied","type":"mot. inf.","class":"infantry","speed":2,"appearance":14,"steps":4,"elite":0,"label":63,"name":"10IN/21+25"},{"nationality":"allied","type":"mot. inf.","class":"infantry","speed":2,"appearance":14,"steps":2,"elite":0,"label":64,"name":"8IN/18"},{"nationality":"allied","type":"mot. inf.","class":"infantry","speed":2,"appearance":14,"steps":4,"elite":0,"label":65,"name":"FF/2"},{"nationality":"allied","type":"artillery","class":"artillery","speed":1,"appearance":14,"steps":4,"elite":0,"label":66,"name":"/B"},{"nationality":"allied","type":"armor","class":"armor","speed":3,"appearance":20,"steps":3,"elite":1,"label":67,"name":"Sher/B"},{"nationality":"allied","type":"armor","class":"armor","speed":3,"appearance":20,"steps":3,"elite":0,"label":68,"name":"8/9"},{"nationality":"allied","type":"armor","class":"armor","speed":3,"appearance":20,"steps":3,"elite":0,"label":69,"name":"8/24"},{"nationality":"allied","type":"armor","class":"armor","speed":3,"appearance":16,"steps":4,"elite":0,"label":71,"name":"10/8"},{"nationality":"allied","type":"armor","class":"armor","speed":3,"appearance":16,"steps":3,"elite":0,"label":72,"name":"10/23"},{"nationality":"allied","type":"mot. inf.","class":"infantry","speed":2,"appearance":16,"steps":4,"elite":0,"label":73,"name":"9AU/26"},{"nationality":"allied","type":"mot. inf.","class":"infantry","speed":2,"appearance":16,"steps":4,"elite":0,"label":74,"name":"9AU/24"},{"nationality":"allied","type":"mot. inf.","class":"infantry","speed":2,"appearance":16,"steps":4,"elite":0,"label":75,"name":"44/131+133"},{"nationality":"allied","type":"mot. inf.","class":"infantry","speed":2,"appearance":16,"steps":2,"elite":0,"label":76,"name":"44/132"},{"nationality":"allied","type":"armor","class":"armor","speed":3,"appearance":18,"steps":3,"elite":1,"label":77,"name":"Sher/A"},{"nationality":"allied","type":"mot. a/t","class":"antitank","speed":2,"appearance":18,"steps":4,"elite":0,"label":78,"name":"6#/B"},{"nationality":"allied","type":"mot. inf.","class":"infantry","speed":2,"appearance":18,"steps":4,"elite":0,"label":79,"name":"51H/154"}] +const units = [{"nationality":"italian","type":"infantry","class":1,"speed":1,"appearance":"S","steps":4,"elite":0,"label":12,"name":"Tre"},{"nationality":"italian","type":"infantry","class":1,"speed":1,"appearance":"S","steps":4,"elite":0,"label":13,"name":"Pav"},{"nationality":"italian","type":"infantry","class":1,"speed":1,"appearance":"S","steps":4,"elite":0,"label":14,"name":"Bre"},{"nationality":"italian","type":"infantry","class":1,"speed":1,"appearance":"S","steps":3,"elite":0,"label":15,"name":"Bol"},{"nationality":"italian","type":"infantry","class":1,"speed":1,"appearance":"S","steps":3,"elite":0,"label":16,"name":"Sav"},{"nationality":"italian","type":"mech. inf.","class":1,"speed":3,"appearance":7,"steps":4,"elite":0,"label":21,"name":"Tri"},{"nationality":"italian","type":"infantry","class":1,"speed":1,"appearance":7,"steps":2,"elite":0,"label":22,"name":"Sab"},{"nationality":"italian","type":"armor","class":0,"speed":3,"appearance":11,"steps":3,"elite":0,"label":23,"name":"Lit"},{"nationality":"italian","type":"mot. inf.","class":1,"speed":2,"appearance":17,"steps":3,"elite":0,"label":24,"name":"Fas"},{"nationality":"italian","type":"mot. inf.","class":1,"speed":2,"appearance":19,"steps":3,"elite":0,"label":25,"name":"Cen"},{"nationality":"italian","type":"infantry","class":1,"speed":1,"appearance":19,"steps":2,"elite":0,"label":26,"name":"Pis"},{"nationality":"italian","type":"para","class":1,"speed":1,"appearance":"M","steps":4,"elite":0,"label":27,"name":"Fol"},{"nationality":"italian","type":"artillery","class":3,"speed":1,"appearance":"S","steps":2,"elite":0,"label":28,"name":"Ita"},{"nationality":"italian","type":"armor","class":0,"speed":3,"appearance":"S","steps":4,"elite":0,"label":29,"name":"Ari"},{"nationality":"german","type":"armor","class":0,"speed":3,"appearance":"S","steps":3,"elite":1,"label":14,"name":"21/5"},{"nationality":"german","type":"recon","class":0,"speed":4,"appearance":"S","steps":1,"elite":1,"label":15,"name":"21/3"},{"nationality":"german","type":"mech. inf.","class":1,"speed":3,"appearance":"S","steps":3,"elite":1,"label":16,"name":"21/104"},{"nationality":"german","type":"recon","class":0,"speed":4,"appearance":3,"steps":1,"elite":1,"label":17,"name":"15/33"},{"nationality":"german","type":"mob. a/t","class":2,"speed":3,"appearance":3,"steps":2,"elite":1,"label":18,"name":"88mm/A"},{"nationality":"german","type":"mech. inf.","class":1,"speed":3,"appearance":3,"steps":3,"elite":1,"label":19,"name":"15/115"},{"nationality":"german","type":"armor","class":0,"speed":3,"appearance":5,"steps":3,"elite":1,"label":21,"name":"15/8"},{"nationality":"german","type":"recon","class":0,"speed":4,"appearance":5,"steps":1,"elite":1,"label":22,"name":"90/580"},{"nationality":"german","type":"mot. inf.","class":1,"speed":2,"appearance":5,"steps":2,"elite":1,"label":23,"name":"90/361"},{"nationality":"german","type":"mot. a/t","class":2,"speed":2,"appearance":5,"steps":2,"elite":1,"label":24,"name":"50mm"},{"nationality":"german","type":"artillery","class":3,"speed":1,"appearance":7,"steps":2,"elite":1,"label":25,"name":"/104"},{"nationality":"german","type":"mot. inf.","class":1,"speed":2,"appearance":7,"steps":2,"elite":1,"label":26,"name":"90/200"},{"nationality":"german","type":"mob. a/t","class":2,"speed":3,"appearance":11,"steps":2,"elite":1,"label":27,"name":"88mm/B"},{"nationality":"german","type":"mech. inf.","class":1,"speed":3,"appearance":11,"steps":2,"elite":1,"label":28,"name":"90/sv288"},{"nationality":"german","type":"mech. inf.","class":1,"speed":3,"appearance":11,"steps":2,"elite":1,"label":29,"name":"90/346"},{"nationality":"german","type":"para","class":1,"speed":1,"appearance":"M","steps":3,"elite":1,"label":31,"name":"Ram"},{"nationality":"german","type":"infantry","class":1,"speed":1,"appearance":"M","steps":3,"elite":1,"label":32,"name":"164/382+433"},{"nationality":"german","type":"infantry","class":1,"speed":1,"appearance":"M","steps":2,"elite":1,"label":33,"name":"164/125"},{"nationality":"german","type":"mech. inf.","class":1,"speed":3,"appearance":3,"steps":3,"elite":1,"label":34,"name":"90/155"},{"nationality":"german","type":"mot. a/t","class":2,"speed":2,"appearance":17,"steps":2,"elite":1,"label":35,"name":"76mm"},{"nationality":"allied","type":"armor","class":0,"speed":3,"appearance":"S","steps":2,"elite":0,"label":14,"name":"2/3"},{"nationality":"allied","type":"mech. inf.","class":1,"speed":3,"appearance":"S","steps":2,"elite":0,"label":15,"name":"2/SG"},{"nationality":"allied","type":"mech. inf.","class":1,"speed":3,"appearance":"S","steps":2,"elite":0,"label":16,"name":"4IN/3m"},{"nationality":"allied","type":"mot. inf.","class":1,"speed":2,"appearance":"S","steps":4,"elite":0,"label":17,"name":"9AU/20"},{"nationality":"allied","type":"mot. inf.","class":1,"speed":2,"appearance":"S","steps":4,"elite":0,"label":18,"name":"70/14+16"},{"nationality":"allied","type":"mot. inf.","class":1,"speed":2,"appearance":"S","steps":3,"elite":0,"label":19,"name":"70/23"},{"nationality":"allied","type":"armor","class":0,"speed":3,"appearance":"T","steps":1,"elite":1,"label":21,"name":"Matilda/A"},{"nationality":"allied","type":"mech. inf.","class":1,"speed":3,"appearance":"T","steps":3,"elite":0,"label":22,"name":"7/SG"},{"nationality":"allied","type":"mech. inf.","class":1,"speed":3,"appearance":"T","steps":3,"elite":0,"label":23,"name":"7/22G"},{"nationality":"allied","type":"mot. inf.","class":1,"speed":2,"appearance":"T","steps":3,"elite":0,"label":24,"name":"/Pol"},{"nationality":"allied","type":"mot. inf.","class":1,"speed":2,"appearance":"T","steps":3,"elite":0,"label":25,"name":"7AU/18"},{"nationality":"allied","type":"artillery","class":3,"speed":1,"appearance":"T","steps":2,"elite":0,"label":26,"name":"/Tob"},{"nationality":"allied","type":"mot. inf.","class":1,"speed":2,"appearance":18,"steps":4,"elite":0,"label":27,"name":"51H/152"},{"nationality":"allied","type":"self prop. arty","class":3,"speed":3,"appearance":18,"steps":2,"elite":0,"label":28,"name":"Priest"},{"nationality":"allied","type":"artillery","class":3,"speed":1,"appearance":18,"steps":4,"elite":0,"label":29,"name":"/C"},{"nationality":"allied","type":"armor","class":0,"speed":3,"appearance":2,"steps":4,"elite":0,"label":31,"name":"7/7"},{"nationality":"allied","type":"mech. inf.","class":1,"speed":3,"appearance":2,"steps":3,"elite":0,"label":32,"name":"4IN/7m"},{"nationality":"allied","type":"mot. inf.","class":1,"speed":2,"appearance":2,"steps":3,"elite":0,"label":33,"name":"4IN/5"},{"nationality":"allied","type":"mot. inf.","class":1,"speed":2,"appearance":2,"steps":3,"elite":0,"label":34,"name":"4IN/11"},{"nationality":"allied","type":"armor","class":0,"speed":3,"appearance":4,"steps":1,"elite":1,"label":35,"name":"Matilda/B"},{"nationality":"allied","type":"i-tank","class":0,"speed":3,"appearance":4,"steps":4,"elite":0,"label":36,"name":"/1AT"},{"nationality":"allied","type":"armor","class":0,"speed":3,"appearance":4,"steps":3,"elite":0,"label":37,"name":"7/4"},{"nationality":"allied","type":"recon","class":0,"speed":4,"appearance":4,"steps":2,"elite":0,"label":38,"name":"7"},{"nationality":"allied","type":"artillery","class":3,"speed":1,"appearance":20,"steps":3,"elite":0,"label":39,"name":"/D"},{"nationality":"allied","type":"mot. a/t","class":2,"speed":2,"appearance":6,"steps":3,"elite":0,"label":41,"name":"2#"},{"nationality":"allied","type":"mech. inf.","class":1,"speed":3,"appearance":6,"steps":4,"elite":0,"label":42,"name":"2NZ/4"},{"nationality":"allied","type":"mech. inf.","class":1,"speed":3,"appearance":6,"steps":4,"elite":0,"label":43,"name":"2NZ/5"},{"nationality":"allied","type":"mech. inf.","class":1,"speed":3,"appearance":6,"steps":4,"elite":0,"label":44,"name":"2NZ/6"},{"nationality":"allied","type":"mot. inf.","class":1,"speed":2,"appearance":6,"steps":4,"elite":0,"label":45,"name":"1SA/2+5"},{"nationality":"allied","type":"mot. inf.","class":1,"speed":2,"appearance":6,"steps":3,"elite":0,"label":46,"name":"1SA/1"},{"nationality":"allied","type":"recon","class":0,"speed":4,"appearance":8,"steps":2,"elite":0,"label":47,"name":"1SA"},{"nationality":"allied","type":"mot. inf.","class":1,"speed":2,"appearance":8,"steps":3,"elite":0,"label":48,"name":"1SA/3"},{"nationality":"allied","type":"mot. inf.","class":1,"speed":2,"appearance":8,"steps":3,"elite":0,"label":49,"name":"2SA/4+6"},{"nationality":"allied","type":"armor","class":0,"speed":3,"appearance":8,"steps":4,"elite":0,"label":51,"name":"1/22"},{"nationality":"allied","type":"i-tank","class":0,"speed":3,"appearance":8,"steps":3,"elite":0,"label":52,"name":"/32AT"},{"nationality":"allied","type":"artillery","class":3,"speed":1,"appearance":8,"steps":2,"elite":0,"label":53,"name":"/A"},{"nationality":"allied","type":"armor","class":0,"speed":3,"appearance":10,"steps":4,"elite":0,"label":54,"name":"1/2"},{"nationality":"allied","type":"mech. inf.","class":1,"speed":3,"appearance":10,"steps":3,"elite":0,"label":55,"name":"1/201G"},{"nationality":"allied","type":"mech. inf.","class":1,"speed":3,"appearance":10,"steps":2,"elite":0,"label":56,"name":"1/SG"},{"nationality":"allied","type":"mot. inf.","class":1,"speed":2,"appearance":10,"steps":3,"elite":0,"label":57,"name":"5IN/29"},{"nationality":"allied","type":"armor","class":0,"speed":3,"appearance":12,"steps":2,"elite":1,"label":58,"name":"Grant"},{"nationality":"allied","type":"mot. a/t","class":2,"speed":2,"appearance":12,"steps":3,"elite":0,"label":59,"name":"6#/A"},{"nationality":"allied","type":"mech. inf.","class":1,"speed":3,"appearance":14,"steps":2,"elite":0,"label":61,"name":"10IN/161m"},{"nationality":"allied","type":"mot. inf.","class":1,"speed":2,"appearance":14,"steps":4,"elite":0,"label":62,"name":"5IN/9+10"},{"nationality":"allied","type":"mot. inf.","class":1,"speed":2,"appearance":14,"steps":4,"elite":0,"label":63,"name":"10IN/21+25"},{"nationality":"allied","type":"mot. inf.","class":1,"speed":2,"appearance":14,"steps":2,"elite":0,"label":64,"name":"8IN/18"},{"nationality":"allied","type":"mot. inf.","class":1,"speed":2,"appearance":14,"steps":4,"elite":0,"label":65,"name":"FF/2"},{"nationality":"allied","type":"artillery","class":3,"speed":1,"appearance":14,"steps":4,"elite":0,"label":66,"name":"/B"},{"nationality":"allied","type":"armor","class":0,"speed":3,"appearance":20,"steps":3,"elite":1,"label":67,"name":"Sher/B"},{"nationality":"allied","type":"armor","class":0,"speed":3,"appearance":20,"steps":3,"elite":0,"label":68,"name":"8/9"},{"nationality":"allied","type":"armor","class":0,"speed":3,"appearance":20,"steps":3,"elite":0,"label":69,"name":"8/24"},{"nationality":"allied","type":"armor","class":0,"speed":3,"appearance":16,"steps":4,"elite":0,"label":71,"name":"10/8"},{"nationality":"allied","type":"armor","class":0,"speed":3,"appearance":16,"steps":3,"elite":0,"label":72,"name":"10/23"},{"nationality":"allied","type":"mot. inf.","class":1,"speed":2,"appearance":16,"steps":4,"elite":0,"label":73,"name":"9AU/26"},{"nationality":"allied","type":"mot. inf.","class":1,"speed":2,"appearance":16,"steps":4,"elite":0,"label":74,"name":"9AU/24"},{"nationality":"allied","type":"mot. inf.","class":1,"speed":2,"appearance":16,"steps":4,"elite":0,"label":75,"name":"44/131+133"},{"nationality":"allied","type":"mot. inf.","class":1,"speed":2,"appearance":16,"steps":2,"elite":0,"label":76,"name":"44/132"},{"nationality":"allied","type":"armor","class":0,"speed":3,"appearance":18,"steps":3,"elite":1,"label":77,"name":"Sher/A"},{"nationality":"allied","type":"mot. a/t","class":2,"speed":2,"appearance":18,"steps":4,"elite":0,"label":78,"name":"6#/B"},{"nationality":"allied","type":"mot. inf.","class":1,"speed":2,"appearance":18,"steps":4,"elite":0,"label":79,"name":"51H/154"}] if (typeof module !== 'undefined') module.exports = { hex_exists, hex_name, hex_road, side_road, side_limit, regions, units } @@ -274,7 +274,7 @@ svg .hex.allied_control { background-image: url(units.svg); background-size: 1000%; border-style: solid; - transition: top 200ms, left 200ms; + transition: top 200ms, left 200ms, transform 200ms; } .unit.italian { @@ -1,5 +1,7 @@ "use strict" +// TODO: intermediate regroup moves + // https://www.redblobgames.com/grids/hexagons/ const svgNS = "http://www.w3.org/2000/svg" @@ -371,7 +373,7 @@ function update_map() { if (stack[hex] === ui.focus) { x = ui.hex_x[hex] - 25 - y = ui.hex_y[hex] - 25 + i * 54 + y = ui.hex_y[hex] - 25 + i * 56 z = 100 } else { if (stack[hex].length <= 1) { @@ -381,11 +383,11 @@ function update_map() { x = ui.hex_x[hex] - 30 + i * 11 y = ui.hex_y[hex] - 30 + i * 14 } else if (stack[hex].length <= 8) { - x = ui.hex_x[hex] - 35 + i * 4 - y = ui.hex_y[hex] - 35 + i * 4 + x = ui.hex_x[hex] - 30 + i * 4 + y = ui.hex_y[hex] - 30 + i * 4 } else { - x = ui.hex_x[hex] - 35 + i * 2 - y = ui.hex_y[hex] - 35 + i * 2 + x = ui.hex_x[hex] - 35 + i * 3 + y = ui.hex_y[hex] - 35 + i * 3 } z = 1 + i } @@ -466,14 +468,16 @@ function update_battle() { update_battle_line(ui.battle_line_1, is_allied_unit) update_battle_line(ui.battle_line_2, is_axis_unit) } - target_button("target_armor") - target_button("target_infantry") - target_button("target_antitank") - target_button("target_artillery") + target_button("armor") + target_button("infantry") + target_button("antitank") + target_button("artillery") + for (let i = 0; i < 4; ++i) + ui.battle_hits[i].textContent = view.hits[i] } function target_button(action) { - let button = document.getElementById(action + "_button") + let button = document.getElementById("target_" + action + "_button") if (view.actions) { button.classList.remove("hide") if (view.actions[action]) @@ -53,6 +53,27 @@ const sidecount = hexcount * 3 const AXIS = 'Axis' const ALLIED = 'Allied' +const firepower_name = [ "0", "1", "2", "3", "TF", "DF", "SF" ] + +const SF = 6 +const DF = 5 +const TF = 4 + +const class_name = [ "armor", "infantry", "anti-tank", "artillery" ] + +const ARMOR = 0 +const INFANTRY = 1 +const ANTITANK = 2 +const ARTILLERY = 3 + +const FIREPOWER_MATRIX = [ + [ SF, DF, SF, TF ], + [ SF, SF, SF, TF ], + [ DF, SF, SF, TF ], + [ SF, DF, DF, SF ], +] + + const CLEAR = 2 const PASS = 1 const ROUGH = 0 @@ -159,20 +180,24 @@ function unit_speed(u) { return units[u].speed } +function unit_class(u) { + return units[u].class +} + function is_artillery_unit(u) { - return units[u].class === 'artillery' + return units[u].class === ARTILLERY } function is_armor_unit(u) { - return units[u].class === 'armor' + return units[u].class === ARMOR } function is_infantry_unit(u) { - return units[u].class === 'infantry' + return units[u].class === INFANTRY } function is_antitank_unit(u) { - return units[u].class === 'antitank' + return units[u].class === ANTITANK } function unit_hex(u) { @@ -191,6 +216,21 @@ function set_unit_lost_steps(u, n) { game.units[u] = (game.units[u] & ~3) | n } +function eliminate_unit(u) { + set_unit_hex(u, 0) + set_unit_lost_steps(u, 0) +} + +function reduce_unit(u) { + let s = unit_steps(u) + let hp = unit_hp_per_step(u) + if (s === 1) + eliminate_unit(u) + else + set_unit_steps(u, s - 1) + return hp +} + function is_unit_supplied(u) { return (game.units[u] & 4) === 4 } @@ -239,6 +279,25 @@ function unit_steps(u) { return units[u].steps - unit_lost_steps(u) } +function is_unit_elite(u) { + return units[u].elite +} + +function unit_cv(u) { + if (is_unit_elite(u)) + return unit_steps(u) * 2 + return unit_steps(u) +} + +function unit_hp_per_step(u) { + // TODO: double defense, minefields, etc + return is_unit_elite(u) ? 2 : 1 +} + +function unit_hp(u) { + return unit_steps(u) * unit_hp_per_step(u) +} + function set_unit_steps(u, n) { set_unit_lost_steps(u, units[u].steps - n) } @@ -395,7 +454,7 @@ function release_hex_control(a) { function is_new_battle_hex(a) { if (is_battle_hex(a)) - return !set_has(game.axis_hexes) && !set_has(game.allied_hexes) + return !set_has(game.axis_hexes, a) && !set_has(game.allied_hexes, a) return false } @@ -1172,7 +1231,9 @@ states.move_who = { game.move_road = 4 }, end_move() { - clear_supply_networks() + game.side_limit = {} + game.rommel = 0 + game.from1 = game.from2 = game.to1 = game.to2 = 0 // TODO goto_combat_phase() } @@ -1455,21 +1516,26 @@ states.select_battle = { gen_action('end_combat') }, hex(x) { - push_undo() + clear_undo() game.battle = x goto_defensive_fire() }, + end_combat() { + end_combat_phase() + } } function goto_defensive_fire() { set_passive_player() game.fired = [] + game.hits = [ 0, 0, 0, 0 ] game.state = 'defensive_fire' } function goto_offensive_fire() { set_active_player() game.fired = [] + game.hits = [ 0, 0, 0, 0 ] game.state = 'offensive_fire' } @@ -1496,27 +1562,179 @@ const xxx_fire = { } }, unit(who) { - clear_undo() - set_unit_fired(who) + game.selected = [ who ] + game.state = game.state + '_target' + }, +} - let done = true +const xxx_fire_target = { + prompt() { + view.prompt = `Select a target class.` + + let hp = [ 0, 0, 0, 0 ] for (let u = 0; u < units.length; ++u) - if (is_friendly_unit(u) && !is_unit_fired(u) && unit_hex(u) === game.battle) - done = false + if (is_enemy_unit(u) && unit_hex(u) === game.battle) + hp[unit_class(u)] += unit_hp(u) + for (let i = 0; i < 4; ++i) + hp[i] -= game.hits[i] + + let who = game.selected[0] + let fc = unit_class(who) + + gen_action_unit(who) // deselect + + // armor must target armor if possible + if (fc === ARMOR && hp[ARMOR] > 0) { + gen_action('armor') + return + } + + // infantry must target infantry if possible + if (fc === INFANTRY && hp[INFANTRY] > 0) { + gen_action('infantry') + return + } + + if (hp[ARMOR] > 0) + gen_action('armor') + if (hp[INFANTRY] > 0) + gen_action('infantry') + if (hp[ANTITANK] > 0) + gen_action('antitank') + + // only artillery may target artillery if other units are alive + if (hp[ARTILLERY] > 0) { + if (fc === ARTILLERY || + (hp[ARTILLERY] <= 0 && hp[INFANTRY] <= 0 && hp[ANTITANK] <= 0)) + gen_action('artillery') + } + }, + unit(u) { + game.selected = [] + resume_fire() + }, + armor() { + let who = game.selected[0] + game.selected = [] + fire_at(who, ARMOR) + }, + infantry() { + let who = game.selected[0] + game.selected = [] + fire_at(who, INFANTRY) + }, + antitank() { + let who = game.selected[0] + game.selected = [] + fire_at(who, ANTITANK) + }, + artillery() { + let who = game.selected[0] + game.selected = [] + fire_at(who, ARTILLERY) + }, +} + +const xxx_fire_hits = { + prompt() { + view.prompt = `Apply hits.` + let done = true + for (let u = 0; u < units.length; ++u) { + if (is_friendly_unit(u) && unit_hex(u) === game.battle) { + if (game.hits[unit_class(u)] > 0) { + gen_action_unit(u) + done = false + } + } + } if (done) - end_fire() + gen_action_next() + }, + unit(who) { + push_undo() + let c = unit_class(who) + game.hits[c] -= reduce_unit(who) + }, + next() { + clear_undo() + if (game.state === 'defensive_fire_hits') { + goto_offensive_fire() + } else { + end_battle() + } }, } -function end_fire() { - if (game.state === 'defensive_fire') - goto_offensive_fire() - else - end_combat_phase() +function roll_fire(who, fp, tc) { + let roll = random(6) + 1 + log(`${who} fired ${firepower_name[fp]} ${roll} at ${class_name[tc]}`) + if (roll >= fp) + return 1 + return 0 +} + +function fire_at(firing, tc) { + let fp = FIREPOWER_MATRIX[unit_class(firing)][tc] + let cv = unit_cv(firing) + + set_unit_fired(firing) + + for (let i = 0; i < cv; ++i) + game.hits[tc] += roll_fire(firing, fp, tc) + + resume_fire() +} + +function resume_fire() { + game.state = game.state.replace("_target", "") + let done = true + for (let u = 0; u < units.length; ++u) + if (is_friendly_unit(u) && !is_unit_fired(u) && unit_hex(u) === game.battle) + done = false + if (done) + goto_fire_hits() +} + +function goto_fire_hits() { + // clamp number of hits to available hp + let hp = [ 0, 0, 0, 0 ] + for (let u = 0; u < units.length; ++u) + if (is_enemy_unit(u) && unit_hex(u) === game.battle) + hp[unit_class(u)] += unit_hp(u) + for (let i = 0; i < 4; ++i) + game.hits[i] = min(game.hits[i], hp[i]) + + if (game.state === 'defensive_fire') { + set_active_player() + game.state = 'defensive_fire_hits' + } else { + set_passive_player() + game.state = 'offensive_fire_hits' + } +} + +function end_battle() { + clear_undo() + set_active_player() + set_delete(game.active_battles, game.battle) + set_delete(game.assault_battles, game.battle) + game.state = 'select_battle' + game.battle = 0 } states.defensive_fire = xxx_fire states.offensive_fire = xxx_fire +states.defensive_fire_target = xxx_fire_target +states.offensive_fire_target = xxx_fire_target +states.defensive_fire_hits = xxx_fire_hits +states.offensive_fire_hits = xxx_fire_hits + +function end_combat_phase() { + // TODO: blitz + // TODO: final supply check + // TODO: supply cards revealed + end_player_turn() +} // === DEPLOYMENT === @@ -2120,6 +2338,7 @@ exports.view = function(state, current) { if (game.battle) view.battle = game.battle if (game.fired) view.fired = game.fired + if (game.hits) view.hits = game.hits if (game.flash) view.flash = game.flash return common_view(current) diff --git a/tools/gendata.js b/tools/gendata.js index 75c3a9f..a4fb97c 100644 --- a/tools/gendata.js +++ b/tools/gendata.js @@ -410,18 +410,23 @@ expand_names(); let units = []; +const ARMOR = 0 +const INFANTRY = 1 +const ANTITANK = 2 +const ARTILLERY = 3 + const class_from_type = { - "recon": "armor", - "armor": "armor", - "i-tank": "armor", - "infantry": "infantry", - "mech. inf.": "infantry", - "mot. inf.": "infantry", - "para": "infantry", - "mob. a/t": "antitank", - "mot. a/t": "antitank", - "self prop. arty": "artillery", - "artillery": "artillery", + "recon": ARMOR, + "armor": ARMOR, + "i-tank": ARMOR, + "infantry": INFANTRY, + "mech. inf.": INFANTRY, + "mot. inf.": INFANTRY, + "para": INFANTRY, + "mob. a/t": ANTITANK, + "mot. a/t": ANTITANK, + "self prop. arty": ARTILLERY, + "artillery": ARTILLERY, } const speed_from_type = { @@ -441,12 +446,12 @@ const speed_from_type = { let unit_map = {}; function def_block(nationality, type, appearance, steps, elite, label, name) { - let type_class = class_from_type[type]; + let klass = class_from_type[type]; let speed = speed_from_type[type]; if (name in unit_map) throw new Error("duplicate block name:", name); unit_map[name] = units.length; - units.push({nationality, type, class: type_class, speed, appearance, steps, elite, label, name}); + units.push({nationality, type, class: klass, speed, appearance, steps, elite, label, name}); } let S = "S"; |