dupuy@amsterdam.columbia.edu (Alexander Dupuy) (07/28/87)
The game Ogre (which I had no trouble compiling) is really wonderful; bringing back the memory of many hours spent playing the paper version. However, there is an inconsistency in the electronic version which I can't figure. Lacking a copy of the paper game, I can't go to the rules. Perhaps someone (the author?) who does can advise. This version of ogre(6) allows you to place the Command Post in a crater. This is an extremely effective defense technique, since it is no longer possible for the Ogre to ram the CP (you can't enter craters, right?). You can just blast away at the batteries and missiles, and once those are gone, take your time at finishing off the treads for the win. You don't even need to take out the anti-personnel guns. In fact, if the CP is in a crater, once the batteries and missiles are gone, you cannot lose the game. The best the Ogre can hope for is a stalemate, by destroying any infantry with AP, and destroying any armor by ramming (not easy) before all its treads are gone. In fact, it is even possible to place the CP on top of another unit (or units of infantry), even though placing units on top of the CP is disallowed. This is definitely an inconsistency. Although I haven't yet beat the Ogre without placing the CP in a crater, the poor checking on CP placement would seem to be a bug. If in fact it violates the rules, here is a fix: *** init.c.dist Mon Jul 27 20:28:10 1987 --- init.c Tue Jul 28 16:08:05 1987 *************** *** 112,118 **** break ; case CP: ! if(cp_set) { bad_char = TRUE; } else { --- 112,118 ---- break ; case CP: ! if(occupied(a, b) || blocked(a, b) || cp_set) { bad_char = TRUE; } else { Some other trivia; there is a sequel to the Ogre game called G.E.V. which pits "defenders" against defenders (no ogre). I don't recollect it fully, but I seem to remember that there were some additional armored unit types. I believe that it was only in G.E.V. (and the re-release of Ogre) that the second movement phase of GEVs was reduced to three hexes in order to bring it more into line with other units (in the original Ogre, GEVs moved 4 + 4). If anyone could send me details, I would be happy to implement the extensions. @alex --- arpanet: dupuy@columbia.edu uucp: ...!seismo!columbia!dupuy
hyc@umix.cc.umich.edu (Howard Chu) (07/30/87)
Actually, AntiPersonnel weapons are sufficient for destroying the Command Post. I have a copy of both Ogre and GEV, but they aren't handy right now. I also have The Ogre Book, which includes such niceties as new scenarios, strategy & tactics, and a few new units, such as the Marks I, II, IV, and VI, as well as a few "hybrid" units. (The Mark IV was also present in GEV.) Several of these newer units are also in GEV, including light tanks, mobile howitzers, and other goodies. Including the units would be no problem, but fixing up the map would be a challenge. In GEV, the map is about 50% larger and has *terrain*. Roads, swamps, forests, rivers, lakes, gullies, cities... Terrain is a Real Nice thing to have in a game of ground based armor units. Ah well. There are also new rules for stacking, ie allowing multiple units per hex, overrun attacks, and other good stuff that would be nice to take into account. Ah well. I can't check to see if this is a real "bug" or not, but I'm gonna keep that patch handy... -- -- Howard Chu UUCP: ...!seismo!umix!hyc ARPA: hyc@umix.cc.umich.edu
dupuy@amsterdam.columbia.edu (Alexander Dupuy) (08/01/87)
I found my copies of Ogre and G.E.V. so I can say that the bug I reported earlier is in fact a bug. The rules state clearly that objects cannot be placed on top of each other, or on craters. Once I had the rules to G.E.V. I couldn't resist adding the new unit types to ogre. So I am enclosing patches to add the Ogre Mark IV, and the 'L' (light tank) and 'B' (mobile howitzer) type units. Note that you get two light tanks for each armor point. If anyone with The Ogre Book can send me the specs on the Mark I, II, and VI Ogres, I can add them as well. Or they can just send out the patches themselves. Anyone who is really inspired could try implementing the terrain rules. Overrun combat is another possibility, but perhaps too complex to be worth it. The Ogre Mark IV has a different missile weapon system, with 3 missile racks, but 15 missiles. Missile racks (but not missiles) can be attacked, and when they are destroyed, one missile is destroyed. Only one missile can be fired per turn per rack (they take time to reload). Missile racks also have a defense of 4 instead of 3. The Mark IV is also faster, with a movement of 4. It has fewer main and secondary batteries, though, so it is considered on a par with the Mark V. To be able to implement all Ogres with the same structure, I modified the the Mark III and Mark V Ogres. They both now have 2 missile racks, and the same number of missiles as before. The justification for this is that there is a rule in Ogre which says they can fire no more than 2 missiles per turn. The Mark V has 6 missiles (according to the Ogre rulebook) not 5. Was this changed in later versions of Ogre (I have the original)? One other discrepancy I noted between the Ogre rules and the implementation is the number of armor and infantry points which the defender gets. The paper rules give you far more points than the program. Is this because the dumb computer needs a handicap? The patches which jpochma@polyslo.UUCP (John H Pochmara) posted to fix up problems with _doprnt() on some machines had a flaw: they failed to erase to end of line, as the display() routine had. The rest of this posting is a set of patches which should be applied to the original ogre, as posted to comp.sources.games (dust off those shar files now). They fix the _doprnt problem, and the CP placement bug. A number of other cosmetic changes are included as well. And of course, the new units and Ogre types. @alex --- arpanet: dupuy@columbia.edu uucp: ...!seismo!columbia!dupuy : This is a shar archive. Extract with sh, not csh. : The rest of this file will extract: : : attack.c.pat : init.c.pat : main.c.pat : map.c.pat : ogre.6.pat : ogre.h.pat : ogrecom.c.pat : ogrestat.c.pat : resolve.c.pat : echo x - attack.c.pat sed 's/^X//' > attack.c.pat << '//go.sysin dd *' X*** attack.c.dist Mon Jul 27 20:28:05 1987 X--- attack.c Fri Jul 31 17:32:00 1987 X*************** X*** 167,194 **** X X case MAIN: X X! display_xy(18, 40, "%d/%d (%s)", allocated.main_bats, DEF_MAIN, X odd_str(allocated.main_bats, DEF_MAIN)); X break; X X case SECONDARY: X X! display_xy(19, 40, "%d/%d (%s)", allocated.sec_bats, DEF_SECONDARY, X odd_str(allocated.sec_bats, DEF_SECONDARY)); X break; X X case MISSILE: X X! display_xy(20, 40, "%s", odd_str(allocated.missiles, DEF_MISSILES)); X break; X X case AP: X X! display_xy(21, 40, "%s", odd_str(allocated.ap, DEF_AP)); X break; X X case TREAD: X! display_xy(22, 40, "1/1 (%d)", allocated.treads); X break; X X } X--- 167,196 ---- X X case MAIN: X X! DISPLAY_XY3(18, 40, "%d/%d (%s)", allocated.main_bats, DEF_MAIN, X odd_str(allocated.main_bats, DEF_MAIN)); X break; X X case SECONDARY: X X! DISPLAY_XY3(19, 40, "%d/%d (%s)", allocated.sec_bats, DEF_SECONDARY, X odd_str(allocated.sec_bats, DEF_SECONDARY)); X break; X X case MISSILE: X X! DISPLAY_XY3(20, 40, "%d/%d (%s)", allocated.missiles, DEF_MISSILES, X! odd_str(allocated.missiles, DEF_MISSILES)); X break; X X case AP: X X! DISPLAY_XY3(21, 40, "%d/%d (%s)", allocated.ap, DEF_AP, X! odd_str(allocated.ap, DEF_AP)); X break; X X case TREAD: X! DISPLAY_XY1(22, 40, "1/1 [%d]", allocated.treads); X break; X X } //go.sysin dd * echo x - init.c.pat sed 's/^X//' > init.c.pat << '//go.sysin dd *' X*** init.c.dist Mon Jul 27 20:28:10 1987 X--- init.c Fri Jul 31 17:58:29 1987 X*************** X*** 8,13 **** X--- 8,14 ---- X init_units(mark) X { X int unitcmp(); X+ char *halve(); X X init_screen(); X X*************** X*** 17,28 **** X switch(mark) { X X case 3: X! armor_points = 10; X infantry_points = 18; X break; X X case 5: X! armor_points = 18; X infantry_points = 27; X break; X } X--- 18,30 ---- X switch(mark) { X X case 3: X! armor_points = 20; X infantry_points = 18; X break; X X+ case 4: X case 5: X! armor_points = 36; X infantry_points = 27; X break; X } X*************** X*** 31,39 **** X cp_set = FALSE; X X while(armor_points > 0 || infantry_points > 0 || !cp_set) { X! display(16, "left to place: %d armor, %d infantry%s", X! armor_points, infantry_points, X! (cp_set) ? "." : ", CP"); X getunit(); X } X X--- 33,41 ---- X cp_set = FALSE; X X while(armor_points > 0 || infantry_points > 0 || !cp_set) { X! DISPLAY3(16, "left to place: %s armor, %d infantry%s", X! halve(armor_points), infantry_points, X! (cp_set) ? "" : ", CP"); X getunit(); X } X X*************** X*** 96,108 **** X } X if (unit[i].type == CP) { X cp_set = FALSE ; X! armor_points += unit[i].movement ; X } X else if (unit[i].type == INFANTRY) infantry_points += 1 ; X! else if (unit[i].type == HOWITZER) armor_points += 2 ; X! else if (unit[i].type == HVYTANK) armor_points += 1 ; X! else if (unit[i].type == MSLTANK) armor_points += 1 ; X! else if (unit[i].type == GEV) armor_points += 1 ; X else broken("Internal error in init!") ; X X if (i < n_free) n_free = i ; X--- 98,112 ---- X } X if (unit[i].type == CP) { X cp_set = FALSE ; X! armor_points += unit[i].movement * 2; X } X else if (unit[i].type == INFANTRY) infantry_points += 1 ; X! else if (unit[i].type == LTTANK) armor_points += 1 ; X! else if (unit[i].type == GEV) armor_points += 2 ; X! else if (unit[i].type == MSLTANK) armor_points += 2 ; X! else if (unit[i].type == HVYTANK) armor_points += 2 ; X! else if (unit[i].type == MHWZ) armor_points += 4 ; X! else if (unit[i].type == HOWITZER) armor_points += 4 ; X else broken("Internal error in init!") ; X X if (i < n_free) n_free = i ; X*************** X*** 112,118 **** X break ; X X case CP: X! if(cp_set) { X bad_char = TRUE; X } X else { X--- 116,122 ---- X break ; X X case CP: X! if(occupied(a, b) || blocked(a, b) || cp_set) { X bad_char = TRUE; X } X else { X*************** X*** 122,139 **** X } X break; X X case HVYTANK: X case MSLTANK: X case GEV: X! if(occupied(a, b) || blocked(a, b) || armor_points == 0) { X bad_char = TRUE; X break; X } X add_unit(a, b, dir); X no_new = FALSE; X! armor_points--; X break; X X case INFANTRY: X dir = '3' ; X case '3': X--- 126,165 ---- X } X break; X X+ case HOWITZER: X+ case MHWZ: X+ if(occupied(a, b) || blocked(a, b) || armor_points <= 3) { X+ bad_char = TRUE; X+ break; X+ } X+ add_unit(a, b, dir); X+ no_new = FALSE; X+ armor_points -= 4; X+ break; X+ X case HVYTANK: X case MSLTANK: X case GEV: X! if(occupied(a, b) || blocked(a, b) || armor_points <= 1) { X bad_char = TRUE; X break; X } X add_unit(a, b, dir); X no_new = FALSE; X! armor_points -= 2; X break; X X+ case LTTANK: X+ X+ if(occupied(a, b) || blocked(a, b) || armor_points <= 0) { X+ bad_char = TRUE; X+ break; X+ } X+ add_unit(a, b, dir); X+ no_new = FALSE; X+ armor_points -= 1; X+ break; X+ X case INFANTRY: X dir = '3' ; X case '3': X*************** X*** 151,172 **** X break ; X } X while (dir--) { X! add_unit(a, b, 'I'); X infantry_points -= 1 ; X } X no_new = FALSE; X break; X X- case HOWITZER: X- if(occupied(a, b) || blocked(a, b) || armor_points <= 1) { X- bad_char = TRUE; X- break; X- } X- add_unit(a, b, dir); X- no_new = FALSE; X- armor_points -= 2; X- break; X- X default: X bad_char = TRUE; X break; X--- 177,188 ---- X break ; X } X while (dir--) { X! add_unit(a, b, INFANTRY); X infantry_points -= 1 ; X } X no_new = FALSE; X break; X X default: X bad_char = TRUE; X break; X*************** X*** 221,234 **** X unit[i].range = 0; X unit[i].defend = 0; X j = 200 ; X! while (j > armor_points || j > 2 || j < 0) { X! display(17, "Movement points for CP? ", 0) ; X j = readchar() ; X j -= '0' ; X } X movecur(17, 0); eeol() ; X unit[i].movement = j; X! armor_points -= j; X break; X X case HVYTANK: X--- 237,250 ---- X unit[i].range = 0; X unit[i].defend = 0; X j = 200 ; X! while (j > armor_points || j > 4 || j < 0) { X! DISPLAY0(17, "Movement points for CP? ") ; X j = readchar() ; X j -= '0' ; X } X movecur(17, 0); eeol() ; X unit[i].movement = j; X! armor_points -= 2 * j; X break; X X case HVYTANK: X*************** X*** 239,244 **** X--- 255,268 ---- X unit[i].movement = 3; X break; X X+ case LTTANK: X+ unit[i].type = LTTANK; X+ unit[i].attack = 2; X+ unit[i].range = 2; X+ unit[i].defend = 2; X+ unit[i].movement = 3; X+ break; X+ X case MSLTANK: X unit[i].type = MSLTANK; X unit[i].attack = 3; X*************** X*** 263,268 **** X--- 287,300 ---- X unit[i].movement = 0; X break; X X+ case MHWZ: X+ unit[i].type = MHWZ; X+ unit[i].attack = 6; X+ unit[i].range = 6; X+ unit[i].defend = 2; X+ unit[i].movement = 1; X+ break; X+ X case INFANTRY: X unit[i].type = INFANTRY; X unit[i].attack = 1; X*************** X*** 324,343 **** X ogre.treads = 45; X ogre.init_treads = 45; X ogre.movement = 3; X ogre.missiles = 2; X ogre.main_bats = 1; X ogre.sec_bats = 4; X ogre.ap = 8; X break; X X case 5: X ogre.treads = 60; X ogre.init_treads = 60; X ogre.movement = 3; X! ogre.missiles = 5; X ogre.main_bats = 2; X ogre.sec_bats = 6; X! ogre.ap = 10; X break; X X } X--- 356,391 ---- X ogre.treads = 45; X ogre.init_treads = 45; X ogre.movement = 3; X+ ogre.init_move = 3; X ogre.missiles = 2; X+ ogre.missracks = 2; X ogre.main_bats = 1; X ogre.sec_bats = 4; X ogre.ap = 8; X break; X X+ case 4: X+ ogre.treads = 60; X+ ogre.init_treads = 60; X+ ogre.movement = 4; X+ ogre.init_move = 4; X+ ogre.missiles = 15; X+ ogre.missracks = 3; X+ ogre.main_bats = 1; X+ ogre.sec_bats = 2; X+ ogre.ap = 8; X+ break; X+ X case 5: X ogre.treads = 60; X ogre.init_treads = 60; X+ ogre.init_move = 3; X ogre.movement = 3; X! ogre.missiles = 6; X! ogre.missracks = 2; X ogre.main_bats = 2; X ogre.sec_bats = 6; X! ogre.ap = 12; X break; X X } X*************** X*** 389,399 **** X--- 437,468 ---- X X break; X X+ case MHWZ: X+ switch(u2 -> type) { X+ X+ case CP: X+ case HOWITZER: X+ cmp = 1; X+ break; X+ X+ case MHWZ: X+ cmp = 0; X+ break; X+ X+ default: X+ cmp = -1; X+ break; X+ X+ } X+ X+ break; X+ X case HVYTANK: X switch(u2 -> type) { X X case CP: X case HOWITZER: X+ case MHWZ: X cmp = 1; X break; X X*************** X*** 412,421 **** X case MSLTANK: X switch(u2 -> type) { X X! case CP: X! case HOWITZER: X! case HVYTANK: X! cmp = 1; X break; X X case MSLTANK: X--- 481,490 ---- X case MSLTANK: X switch(u2 -> type) { X X! case INFANTRY: X! case LTTANK: X! case GEV: X! cmp = -1; X break; X X case MSLTANK: X*************** X*** 423,429 **** X break; X X default: X! cmp = -1; X break; X X } X--- 492,498 ---- X break; X X default: X! cmp = 1; X break; X X } X*************** X*** 434,439 **** X--- 503,509 ---- X switch(u2 -> type) { X X case INFANTRY: X+ case LTTANK: X cmp = -1; X break; X X*************** X*** 449,454 **** X--- 519,543 ---- X X break; X X+ case LTTANK: X+ switch(u2 -> type) { X+ X+ case INFANTRY: X+ cmp = -1; X+ break; X+ X+ case LTTANK: X+ cmp = 0; X+ break; X+ X+ default: X+ cmp = 1; X+ break; X+ X+ } X+ X+ break; X+ X case INFANTRY: X switch(u2 -> type) { X X*************** X*** 470,479 **** X X } X X! broken(thing) char *thing; { X X! clear_screen() ; X! reset_term() ; X! printf("Internal error: %s\n", thing) ; X! exit(1) ; X! } X--- 559,578 ---- X X } X X! char *halve(number) X! int number; X! { X! static char buffer[16]; X X! sprintf(buffer, "%d%s", number / 2, (number % 2) ? ".5" : ""); X! return(buffer); X! } X! X! broken(thing) X! char *thing; X! { X! clear_screen() ; X! reset_term() ; X! printf("Internal error: %s\n", thing) ; X! exit(1) ; X! } //go.sysin dd * echo x - main.c.pat sed 's/^X//' > main.c.pat << '//go.sysin dd *' X*** main.c.dist Mon Jul 27 20:28:13 1987 X--- main.c Wed Jul 29 00:26:32 1987 X*************** X*** 32,37 **** X--- 32,41 ---- X mark = 3; X break; X X+ case '4': X+ mark = 4; X+ break; X+ X case '5': X mark = 5; X break; X*************** X*** 61,67 **** X move_def(); X attack_def(); X X! /* Let the GEVs move their extra 3 turns. */ X init_gev2(); X move_def(); X X--- 65,71 ---- X move_def(); X attack_def(); X X! /* Let the GEVs move their extra 3 hexes. */ X init_gev2(); X move_def(); X //go.sysin dd * echo x - map.c.pat sed 's/^X//' > map.c.pat << '//go.sysin dd *' X*** map.c.dist Mon Jul 27 20:28:16 1987 X--- map.c Fri Jul 31 17:51:27 1987 X*************** X*** 310,377 **** X switch(unit[i].type) { X X case HOWITZER: X! display(16, "%s howitzer (%d/%d D%d M%d)", action, X unit[i].attack, unit[i].range, X unit[i].defend, unit[i].moves_left); X break; X X case MSLTANK: X! display(16, "%s missile tank (%d/%d D%d M%d)", action, X unit[i].attack, unit[i].range, X unit[i].defend, unit[i].moves_left); X break; X X case GEV: X! display(16, "%s GEV (%d/%d D%d M%d)", action, X unit[i].attack, unit[i].range, X unit[i].defend, unit[i].moves_left); X break; X X! case HVYTANK: X! display(16, "%s heavy tank (%d/%d D%d M%d)", action, X unit[i].attack, unit[i].range, X unit[i].defend, unit[i].moves_left); X break; X X case INFANTRY: X! display(16, "%s infantry (%d/%d D%d M%d)", action, X unit[i].attack, unit[i].range, X unit[i].defend, unit[i].moves_left); X break; X X case CP: X! display(16, "%s CP (%d/%d D%d M%d)", action, X unit[i].attack, unit[i].range, X unit[i].defend, unit[i].moves_left); X break; X } X X } X- X- /* VARARGS */ X- display(line, format, args) X- int line; X- char *format; X- int args; X- { X- X- movecur(line, 0); X- eeol(); X- _doprnt(format, &args, stdout); X- X- } X- X- /* VARARGS */ X- display_xy(line, col, format, args) X- int line, col; X- char *format; X- int args; X- { X- X- movecur(line, col); X- eeol(); X- _doprnt(format, &args, stdout); X- X- } X- X- X--- 310,365 ---- X switch(unit[i].type) { X X case HOWITZER: X! DISPLAY5(16, "%s howitzer (%d/%d D%d M%d)", action, X unit[i].attack, unit[i].range, X unit[i].defend, unit[i].moves_left); X break; X X+ case MHWZ: X+ DISPLAY5(16, "%s mobile howitzer (%d/%d D%d M%d)", action, X+ unit[i].attack, unit[i].range, X+ unit[i].defend, unit[i].moves_left); X+ break; X+ X+ case HVYTANK: X+ DISPLAY5(16, "%s heavy tank (%d/%d D%d M%d)", action, X+ unit[i].attack, unit[i].range, X+ unit[i].defend, unit[i].moves_left); X+ break; X+ X case MSLTANK: X! DISPLAY5(16, "%s missile tank (%d/%d D%d M%d)", action, X unit[i].attack, unit[i].range, X unit[i].defend, unit[i].moves_left); X break; X X case GEV: X! DISPLAY5(16, "%s GEV (%d/%d D%d M%d)", action, X unit[i].attack, unit[i].range, X unit[i].defend, unit[i].moves_left); X break; X X! case LTTANK: X! DISPLAY5(16, "%s light tank (%d/%d D%d M%d)", action, X unit[i].attack, unit[i].range, X unit[i].defend, unit[i].moves_left); X break; X X case INFANTRY: X! DISPLAY5(16, "%s infantry (%d/%d D%d M%d)", action, X unit[i].attack, unit[i].range, X unit[i].defend, unit[i].moves_left); X break; X X case CP: X! DISPLAY5(16, "%s CP (%d/%d D%d M%d)", action, X unit[i].attack, unit[i].range, X unit[i].defend, unit[i].moves_left); X break; X+ X+ default: X+ broken("Internal error in describe_action!"); X+ X } X X } //go.sysin dd * echo x - ogre.6.pat sed 's/^X//' > ogre.6.pat << '//go.sysin dd *' X*** ogre.6.dist Mon Jul 27 20:28:20 1987 X--- ogre.6 Fri Jul 31 19:34:32 1987 X*************** X*** 3,9 **** X .SH NAME X Ogre - a game of tank warfare in the 21st century. X .SH SYNOPSIS X! /usr/games/ogre [ogre type (3 or 5)] X .SH DESCRIPTION X .PP X Ogre is a game of tank warfare in the 21st century. You command a force of X--- 3,9 ---- X .SH NAME X Ogre - a game of tank warfare in the 21st century. X .SH SYNOPSIS X! /usr/games/ogre [ogre type (3, 4 or 5)] X .SH DESCRIPTION X .PP X Ogre is a game of tank warfare in the 21st century. You command a force of X*************** X*** 32,40 **** X--- 32,42 ---- X place a: X X H howitzer X+ B mobile howitzer X T heavy tank X M missile tank X G GEV X+ L light tank X 1 1 infantry unit X 2 2 infantry units X 3 3 infantry units X*************** X*** 108,114 **** X 5) Second movement phase for GEVs. Just like step 3, except that only GEVs X can move. X .PP X! 6) The Ogre moves. If it runs over any of your units, they are damaged X or destroyed. X .PP X 7) The Ogre fires at all units in range. Destroyed units are removed from X--- 110,116 ---- X 5) Second movement phase for GEVs. Just like step 3, except that only GEVs X can move. X .PP X! 6) The Ogre moves. If it runs over any of your units, they may be disabled X or destroyed. X .PP X 7) The Ogre fires at all units in range. Destroyed units are removed from X*************** X*** 131,138 **** X The display "a/r Dd Mm" means the unit concerned attacks at a, at range r, X defends at d, and moves m hexes per turn. X .PP X! The Ogre by default is a Mark III. An argument of '5' on the command line X! makes it a Mark V, and gives you more armor points. X .PP X The game can be interrupted at any point with a control-C. There's now X no way to restart. X--- 133,140 ---- X The display "a/r Dd Mm" means the unit concerned attacks at a, at range r, X defends at d, and moves m hexes per turn. X .PP X! The Ogre by default is a Mark III. An argument of '4' or '5' on the command X! line makes it a Mark IV or Mark V, and gives you more armor points. X .PP X The game can be interrupted at any point with a control-C. There's now X no way to restart. X*************** X*** 153,155 **** X--- 155,159 ---- X .PP X The Ogre sometimes gets confused and doesn't know where to go, so it X oscillates from one hex to another, and then back. X+ X+ Ogre Mark IVs don't use their missilies as effectively as they could. //go.sysin dd * echo x - ogre.h.pat sed 's/^X//' > ogre.h.pat << '//go.sysin dd *' X*** ogre.h.dist Mon Jul 27 20:28:21 1987 X--- ogre.h Fri Jul 31 18:13:07 1987 X*************** X*** 17,22 **** X--- 17,23 ---- X typedef struct { X X char missiles; X+ char missracks; X char main_bats; X char sec_bats; X char ap; X*************** X*** 26,31 **** X--- 27,33 ---- X char l_hex; X char r_hex; X char init_treads; X+ char init_move; X char where; X X } OGRE; X*************** X*** 33,45 **** X /* unit types */ X X #define CP 'C' X #define HVYTANK 'T' X #define MSLTANK 'M' X #define GEV 'G' X! #define HOWITZER 'H' X #define INFANTRY 'I' X X X /* unit statuses */ X #define OK 1 X #define DISABLED 2 X--- 35,63 ---- X /* unit types */ X X #define CP 'C' X+ #define HOWITZER 'H' X+ #define MHWZ 'B' X #define HVYTANK 'T' X #define MSLTANK 'M' X #define GEV 'G' X! #define LTTANK 'L' X #define INFANTRY 'I' X X+ /* display macros */ X X+ #define DISPLAY0(l,f) movecur(l,0);eeol();printf(f) X+ #define DISPLAY1(l,f,ar) movecur(l,0);eeol();printf(f,ar) X+ #define DISPLAY2(l,f,ar1,ar2) movecur(l,0);eeol();printf(f,ar1,ar2) X+ #define DISPLAY3(l,f,ar1,ar2,ar3) movecur(l,0);eeol();printf(f,ar1,ar2,ar3) X+ #define DISPLAY4(l,f,ar1,ar2,ar3,ar4) movecur(l,0);eeol();printf(f,ar1,ar2,ar3,ar4) X+ #define DISPLAY5(l,f,ar1,ar2,ar3,ar4,ar5) movecur(l,0);eeol();printf(f,ar1,ar2,ar3,ar4,ar5) X+ X+ #define DISPLAY_XY1(l,c,f,ar) movecur(l,c);eeol();printf(f,ar) X+ #define DISPLAY_XY2(l,c,f,ar1,ar2) movecur(l,c);eeol();printf(f,ar1,ar2) X+ #define DISPLAY_XY3(l,c,f,ar1,ar2,ar3) movecur(l,c);eeol();printf(f,ar1,ar2,ar3) X+ #define DISPLAY_XY4(l,c,f,ar1,ar2,ar3,ar4) movecur(l,c);eeol();printf(f,ar1,ar2,ar3,ar4) X+ #define DISPLAY_XY5(l,c,f,ar1,ar2,ar3,ar4,ar5) movecur(l,c);eeol();printf(f,ar1,ar2,ar3,ar4,ar5) X+ X /* unit statuses */ X #define OK 1 X #define DISABLED 2 X*************** X*** 62,68 **** X X #define N_UNITS 47 X X! #define DEF_MISSILES 3 X #define DEF_MAIN 4 X #define DEF_SECONDARY 3 X #define DEF_AP 1 X--- 80,86 ---- X X #define N_UNITS 47 X X! #define DEF_MISSILES 4 X #define DEF_MAIN 4 X #define DEF_SECONDARY 3 X #define DEF_AP 1 //go.sysin dd * echo x - ogrecom.c.pat sed 's/^X//' > ogrecom.c.pat << '//go.sysin dd *' X*** ogrecom.c.dist Mon Jul 27 20:28:24 1987 X--- ogrecom.c Fri Jul 31 17:49:14 1987 X*************** X*** 5,10 **** X--- 5,14 ---- X X #include "ext.h" X X+ #define INCR(i) i = (i == n_units - 1) ? 0 : i + 1 X+ X+ #define MIN(a, b) (((a) < (b)) ? (a) : (b)) X+ X move_ogre() X { X X*************** X*** 62,68 **** X osccnt = 0; X oscdir = max; X X! /* display(17, "max %d weight %d cnt %d odir %d ndir %d", X max, weight[max], osccnt, oscdir, mapdir[oscdir]); X cycle(); */ X X--- 66,72 ---- X osccnt = 0; X oscdir = max; X X! /* DISPLAY5(17, "max %d weight %d cnt %d odir %d ndir %d", X max, weight[max], osccnt, oscdir, mapdir[oscdir]); X cycle(); */ X X*************** X*** 133,139 **** X int to_target; X int i; X X! total_attacks = ogre.missiles + ogre.main_bats + ogre.sec_bats; X X for(i = 1; i < n_units; i++) { X X--- 137,144 ---- X int to_target; X int i; X X! total_attacks = MIN(ogre.missracks, ogre.missiles) X! + ogre.main_bats + ogre.sec_bats; X X for(i = 1; i < n_units; i++) { X X*************** X*** 153,159 **** X X if(total_attacks <= 0) continue; X X! if(to_target <= RANGE_MISSILES && ogre.missiles > 0) { X weight += unit[i].attack; X weight += 4 - unit[i].movement; X total_attacks -= 1; X--- 158,165 ---- X X if(total_attacks <= 0) continue; X X! if(to_target <= RANGE_MISSILES X! && MIN(ogre.missracks, ogre.missiles) > 0) { X weight += unit[i].attack; X weight += 4 - unit[i].movement; X total_attacks -= 1; X*************** X*** 191,197 **** X X if(off_map(a, b) || blocked(a, b)) weight = - INFINITY; X /* X! display(17, "%d %d weight %d", a, b, weight); cycle(); X */ X X return(weight); X--- 197,203 ---- X X if(off_map(a, b) || blocked(a, b)) weight = - INFINITY; X /* X! DISPLAY3(17, "%d %d weight %d", a, b, weight); cycle(); X */ X X return(weight); X*************** X*** 198,207 **** X X } X X- #define INCR(i) i = (i == n_units - 1) ? 0 : i + 1 X- X- #define MIN(a, b) (((a) > (b)) ? (a) : (b)) X- X /* X Figure out who the Ogre will fire at. In this code, the "fired" element X of the unit description is the number of hit points assigned against that X--- 204,209 ---- X*************** X*** 272,278 **** X X unitno = nextunit(RANGE_MISSILES, unitno); X X! nmissiles = ogre.missiles; X X for(i = 0; i < nmissiles; i++) { X X--- 274,280 ---- X X unitno = nextunit(RANGE_MISSILES, unitno); X X! nmissiles = MIN(ogre.missracks, ogre.missiles); X X for(i = 0; i < nmissiles; i++) { X X*************** X*** 299,305 **** X { X X fflush(stdout); X! sleep(1); X X } X X--- 301,307 ---- X { X X fflush(stdout); X! sleep(2); X X } X X*************** X*** 314,320 **** X /* No point if the unit is already destroyed. */ X if(unit[target].status == DESTROYED) return; X X! display(16, "Ogre fires %s at unit at hex %d%d", weapon, X unit[target].l_hex, unit[target].r_hex); X X movecur_hex(unit[target].l_hex, unit[target].r_hex); X--- 316,322 ---- X /* No point if the unit is already destroyed. */ X if(unit[target].status == DESTROYED) return; X X! DISPLAY3(16, "Ogre fires %s at unit at hex %d%d", weapon, X unit[target].l_hex, unit[target].r_hex); X X movecur_hex(unit[target].l_hex, unit[target].r_hex); //go.sysin dd * echo x - ogrestat.c.pat sed 's/^X//' > ogrestat.c.pat << '//go.sysin dd *' X*** ogrestat.c.dist Mon Jul 27 20:28:26 1987 X--- ogrestat.c Fri Jul 31 19:25:12 1987 X*************** X*** 19,50 **** X 1234567890123456789012345678901234567890 */ X X if(redraw || last.main_bats != ogre.main_bats) X! if(ogre.main_bats > 0) X! display(18, "Main Batteries: %d (4/3 D4)", ogre.main_bats); X! else display(18, " "); X X if(redraw || last.sec_bats != ogre.sec_bats) X! if(ogre.sec_bats > 0) X! display(19, "Secondary Batteries: %d (3/2 D3)", ogre.sec_bats); X! else display(19, " "); X X! if(redraw || last.missiles != ogre.missiles) X! if(ogre.missiles > 0) X! display(20, "Missiles: %d (6/5 D3)", ogre.missiles); X! else display(20, " "); X X if(redraw || last.ap != ogre.ap) X! if(ogre.ap > 0) X! display(21, "Anti-personnel: %2d (1/1 D1)", ogre.ap); X! else display(21, " "); X X if(redraw || last.treads != ogre.treads) X! if(ogre.treads > 0) X! display(22, "Treads: %2d (1/* D1)", ogre.treads); X! else display(22, " "); X X! if(redraw || last.movement != ogre.movement) X! display(23, "Movement: %d", ogre.movement); X X copy(&last, &ogre, sizeof(last)); X X--- 19,52 ---- X 1234567890123456789012345678901234567890 */ X X if(redraw || last.main_bats != ogre.main_bats) X! if(ogre.main_bats > 0) { X! DISPLAY1(18, "Main Batteries: %d (4/3 D4)", ogre.main_bats); X! } else { DISPLAY0(18, " ");} X X if(redraw || last.sec_bats != ogre.sec_bats) X! if(ogre.sec_bats > 0) { X! DISPLAY1(19, "Secondary Batteries: %d (3/2 D3)", ogre.sec_bats); X! } else { DISPLAY0(19, " ");} X X! if(redraw || last.missiles != ogre.missiles X! || last.missracks != ogre.missracks) X! if(ogre.missracks > 0 && ogre.missiles > 0) { X! DISPLAY2(20, "Missiles: %-2d Racks: %d (6/5 D4)", X! ogre.missiles, ogre.missracks); X! } else { DISPLAY0(20, " "); } X X if(redraw || last.ap != ogre.ap) X! if(ogre.ap > 0) { X! DISPLAY1(21, "Anti-personnel: %2d (1/1 D1)", ogre.ap); X! } else { DISPLAY0(21, " ");} X X if(redraw || last.treads != ogre.treads) X! if(ogre.treads > 0) { X! DISPLAY1(22, "Treads: %2d (1/* D1)", ogre.treads); X! } else { DISPLAY0(22, " ");} X X! if(redraw || last.movement != ogre.movement) { X! DISPLAY1(23, "Movement: %d", ogre.movement);} X X copy(&last, &ogre, sizeof(last)); X //go.sysin dd * echo x - resolve.c.pat sed 's/^X//' > resolve.c.pat << '//go.sysin dd *' X*** resolve.c.dist Mon Jul 27 20:28:28 1987 X--- resolve.c Fri Jul 31 17:28:04 1987 X*************** X*** 57,67 **** X OGRE *allocations; X { X X! display(16, "Resolving..."); cycle(); X X if(allocations -> missiles > 0) { X if(crt[roll()][odds(allocations -> missiles, DEF_MISSILES)] == X! DESTROYED) ogre.missiles -= 1; X } X X if(allocations -> main_bats > 0) { X--- 57,71 ---- X OGRE *allocations; X { X X! DISPLAY0(16, "Resolving..."); cycle(); X X if(allocations -> missiles > 0) { X if(crt[roll()][odds(allocations -> missiles, DEF_MISSILES)] == X! DESTROYED) { X! ogre.missracks -= 1; X! ogre.missiles -= 1; X! } X! X } X X if(allocations -> main_bats > 0) { X*************** X*** 213,220 **** X ogre.treads -= attack; X ogre.movement = 0; X if(ogre.treads > 0) ogre.movement = 1; X! if(ogre.treads > ogre.init_treads / 3) ogre.movement = 2; X! if(ogre.treads > 2 * ogre.init_treads / 3) ogre.movement = 3; X X } X X--- 217,225 ---- X ogre.treads -= attack; X ogre.movement = 0; X if(ogre.treads > 0) ogre.movement = 1; X! if(ogre.treads > ogre.init_treads / ogre.init_move) ogre.movement = 2; X! if(ogre.treads > (2 * ogre.init_treads)/ ogre.init_move) ogre.movement = 3; X! if(ogre.treads > (3 * ogre.init_treads)/ ogre.init_move) ogre.movement = 4; X X } X //go.sysin dd * exit --- arpanet: dupuy@columbia.edu uucp: ...!seismo!columbia!dupuy