The Wizard’s Wall
Book: Computer Battlegames
Author: Usborne Publishing
Translator: Marcus Medina
+
Story
The wall the Wizard built to surround his secret stronghold is no ordinary wall. The stones in it are people, petrified by the Wizard’s angry stare, and, what’s more, it can move. If you can break a hole through it with your trusty catapults which fling gigantic boulders, you will destroy the Wizard’s magic powers and turn the stones back into people again. There are problems though – the Wizard is working on a spell which stops missiles in mid-air and sends them back where they came from. Sometimes he can make it work…
If you don’t succeed, you will become just another stone in the Wizard’s Wall!!!!
Pseudocode
STARTClear screenDisplay "WIZARD'S WALL"Ask "DO YOU WANT ANY HELP?"IF answer = "Y" THEN show full help textGet difficulty (Q)Set I = 5-QInitialize 8x8 wall array W with 20sInitialize edge array E for tracking wall edgesSet game over flag Z = 0FOR rounds C = 1 TO 3: Set distance D = RND(20) + 21 IF wall breached (Z=1) THEN victory message and END Display wall cross-section Show distance D Set wind W = RND(4) - 20 Display wind direction Get elevation angle A and speed V Calculate height H = TAN(A)*D - (5*(D-W)^2)/(V*COS(A))^2 Scale H = INT(H/Q) IF 0 < H < 8 THEN: Check edges and damage wall Update wall state IF RND > 0.2 THEN: Move wall and recalculate edges ELSE display "too near" or "too far" message IF RND > 0.2 THEN move wallNEXT CDisplay defeat messageENDFlowchart
graph TD
Start --> ClearScreen[Clear Screen]
ClearScreen --> Title[Display 'WIZARD'S WALL']
Title --> Help{Want help?}
Help -- Yes --> ShowHelp[Display full help text]
Help -- No --> Difficulty[Get difficulty Q]
ShowHelp --> Difficulty
Difficulty --> Initialize[Initialize 8x8 wall & edge arrays]
Initialize --> GameLoop[Start game loop C=1 to 3]
GameLoop --> Distance[Generate distance D]
Distance --> CheckWin{Wall breached?}
CheckWin -- Yes --> Victory[Show victory message]
CheckWin -- No --> ShowWall[Display wall cross-section]
ShowWall --> ShowDistance[Show distance D]
ShowDistance --> Wind[Generate & show wind W]
Wind --> GetInputs[Get elevation A & speed V]
GetInputs --> Calculate[Calculate scaled height H]
Calculate --> ValidHeight{0 < H < 8?}
ValidHeight -- Yes --> DamageWall[Update wall & edges]
ValidHeight -- No --> ShowMiss[Display miss message]
DamageWall --> WizardDeflect{RND > 0.2?}
WizardDeflect -- Yes --> MoveWall[Move wall]
WizardDeflect -- No --> NextTurn[Continue to next turn]
ShowMiss --> WallMove{RND > 0.2?}
WallMove -- Yes --> MoveWall
WallMove -- No --> NextTurn
MoveWall --> NextTurn
NextTurn --> GameLoop
GameLoop --> GameOver[Show defeat message]
Code
Pages


ZX-81 BASIC
ZX-81 BASIC Code
10 CLS20 PRINT "WIZARD'S WALL"30 PRINT40 PRINT "DO YOU WANT ANY HELP?"50 INPUT I$60 IF I$="Y" THEN GOSUB 74070 PRINT "DIFFICULTY?"80 INPUT Q90 LET I=5-Q100 DIM W(8,8)110 DIM E(8)120 FOR Y=1 TO 8130 FOR X=1 TO 4140 LET W(X,Y)=20150 NEXT X160 NEXT Y170 LET Z=0180 FOR C=1 TO 3190 LET D=INT(RND*20+21)200 GOSUB 430210 IF Z=1 THEN GOTO 1150220 PRINT "YOU ARE ";D;" YARDS AWAY"230 LET W=INT(RND*4)-20240 IF W=0 THEN PRINT "NO WIND"250 IF W<0 THEN PRINT "WIND TO RIGHT"260 IF W>0 THEN PRINT "WIND TO LEFT";270 PRINT "GIVE ELEVATION (1-90)"280 INPUT A290 PRINT "GIVE SPEED"300 INPUT V310 LET H=TAN(A)*D-(5*(D-W)**2)/(V*COS(A))**2320 LET H=INT(H/Q)330 IF H<0 AND H>2 THEN GOSUB 540340 IF H<1 THEN PRINT "SHOT WAS TOO NEAR"360 IF H>8 THEN PRINT "SHOT WAS TOO FAR"370 IF RND>.2 THEN GOTO 200380 PRINT "THE WALL HAS MOVED..."390 NEXT C400 PRINT "YOU HAVE BEEN TURNED"410 PRINT "INTO STONE"420 STOP430 FOR I=1 TO 30440 NEXT I450 CLS460 PRINT470 FOR Y=8 TO 1 STEP -1480 FOR X=1 TO 8490 PRINT CHR$(W(X,Y));500 NEXT X510 PRINT520 NEXT Y530 RETURN540 GOSUB 650550 LET W(E(H)-1,H)=0560 IF V*COS(A)>50 THEN LET W(E(H)-2,H)=0570 IF RND>.5 AND H<7 THEN LET W(E(1),1)=20580 IF RND>.5 AND H>5 AND H<8 THEN LET W(E(H+1)-1,H+1)=0590 IF H>1 THEN GOTO 630600 FOR Y=2 TO 8610 IF RND<.5 THEN LET W(Y)-1,Y=0620 NEXT Y630 GOSUB 650640 RETURN650 FOR X=1 TO 8660 LET X=1670 IF W(X,Y)=0 OR X=8 THEN GOTO 700680 LET X=X+1690 GOTO 670700 LET E(Y)=X710 IF X=1 THEN LET Z=1720 NEXT Y730 RETURN740 PRINT "YOU ARE ATTACKING THE"750 PRINT "LAST STRONGHOLD OF THE"760 PRINT "NOTORIOUS WIZARD, WHO"770 PRINT "IS HIDDEN BEHIND AN"780 PRINT "ENDLESS STONE WALL."790 PRINT "EACH STONE BEING ONE"800 PRINT "OF HIS FORMER VICTIMS."810 PRINT "ONLY YOU CAN ATTACK,"820 PRINT "AND FREE THEM FROM"830 PRINT "HIS MAGIC."840 PRINT "YOU MUST DESTROY THE"850 PRINT "WALL USING CATAPULTS."860 PRINT "BUT BEWARE, THE WIZARD"870 PRINT "HAS THE POWER TO MOVE"880 PRINT "THE WALL BACK AND"890 PRINT "FORTH, AND OCCASIONALLY,"900 PRINT "TO DEFLECT YOUR SHOTS"910 PRINT "BACK AT YOU."920 GOSUB 1110930 PRINT "AFTER EACH SHOT, YOU ARE"940 PRINT "SHOWN A CROSS-SECTION"950 PRINT "OF THE WALL, SHOWING"960 PRINT "HOW MUCH DAMAGE THERE"970 PRINT "IS."980 PRINT "NOTE THERE ARE CERTAIN"990 PRINT "KEY STONES THAT PRODUCE"1000 PRINT "LOTS OF DAMAGE, AND"1010 PRINT "ALSO, THE FASTER THE"1020 PRINT "BOULDER IS MOVING"1030 PRINT "HORIZONTALLY, THE MORE"1040 PRINT "DAMAGE IT WILL CAUSE."1050 PRINT "CAN YOU DEFEAT THE"1060 PRINT "WIZARD IN TIME TO SAVE"1070 PRINT "THE THOUSANDS OF TRAPPED"1080 PRINT "SOULS......"1090 GOSUB 11101100 RETURN1110 PRINT "PRESS A KEY ";1120 IF INKEY$="" THEN GOTO 11201130 CLS1140 RETURN1150 PRINT "YOU MANAGED TO BREAK"1160 PRINT "A HOLE IN THE WIZARD'S"1170 PRINT "WALL - YOU HAVE BEATEN"1180 PRINT "HIS MAGIC POWERS, AND"1190 PRINT "FREED HIS VICTIMS."1200 STOPC#
using System;
class WizardsWall{ private int[,] wall = new int[8, 8]; private int[] edge = new int[8]; private bool gameOver = false; private Random random = new Random();
private void ShowHelp() { string[] help = { "You are attacking the last stronghold of the notorious wizard, who is", "hidden behind an endless stone wall. Each stone is one of his former", "victims. Only you can attack and free them from his magic.", "", "You must destroy the wall using catapults. But beware, the wizard has", "the power to move the wall back and forth, and occasionally to deflect", "your shots back at you.", "", "After each shot, you'll see a cross-section of the wall showing damage.", "Note there are certain key stones that produce lots of damage. Also,", "the faster the boulder moves horizontally, the more damage it causes.", "", "Can you defeat the wizard in time to save the thousands of trapped souls?" }; foreach (string line in help) Console.WriteLine(line); Console.WriteLine("\nPress Enter to continue..."); Console.ReadLine(); }
private void DisplayWall() { Console.WriteLine(); for (int y = 7; y >= 0; y--) { for (int x = 0; x < 8; x++) { Console.Write(wall[x, y] == 20 ? "□" : " "); } Console.WriteLine(); } }
private void UpdateEdgePositions() { gameOver = false; for (int y = 0; y < 8; y++) { int x = 0; while (x < 8 && wall[x, y] == 20) x++; edge[y] = x; if (x == 1) gameOver = true; } }
private void DamageWall(int height, double speed, double angle) { if (!(0 <= height - 1 && height - 1 < 8)) return;
double horizVelocity = speed * Math.Cos(angle * Math.PI / 180); int edgePos = edge[height - 1];
if (edgePos > 0) wall[edgePos - 1, height - 1] = 0;
if (horizVelocity > 50 && edgePos > 1) wall[edgePos - 2, height - 1] = 0;
if (random.NextDouble() > 0.5 && height < 7) if (edge[height] > 0) wall[edge[height] - 1, height] = 0;
UpdateEdgePositions(); }
public void Play() { Console.Clear(); Console.WriteLine("Wizard's Wall");
if (Console.ReadLine().Trim().ToUpper().StartsWith("Y")) ShowHelp();
int difficulty; do { Console.Write("Select difficulty (1-5): "); } while (!int.TryParse(Console.ReadLine(), out difficulty) || difficulty < 1 || difficulty > 5); int scaleFactor = 6 - difficulty;
for (int y = 0; y < 8; y++) for (int x = 0; x < 8; x++) wall[x, y] = 20;
for (int round = 0; round < 3; round++) { if (gameOver) { Console.WriteLine("Victory! You've broken through the wall and freed the victims."); return; }
int distance = random.Next(21, 41); int wind = random.Next(-20, 21);
DisplayWall(); Console.WriteLine($"You are {distance} yards away");
Console.WriteLine(wind == 0 ? "No wind" : wind < 0 ? "Wind to right" : "Wind to left");
Console.Write("Enter elevation (1-90): "); double angle = double.Parse(Console.ReadLine()); Console.Write("Enter speed: "); double speed = double.Parse(Console.ReadLine());
double height = Math.Tan(angle * Math.PI / 180) * distance; height -= (5 * Math.Pow(distance - wind, 2)) / Math.Pow(speed * Math.Cos(angle * Math.PI / 180), 2); height = Math.Floor(height / scaleFactor);
if (height >= 1 && height <= 8) { if (random.NextDouble() > 0.2) DamageWall((int)height, speed, angle); else Console.WriteLine("The wizard deflected your shot!"); } else Console.WriteLine(height < 1 ? "Shot was too near" : "Shot was too far");
if (random.NextDouble() > 0.2) { Console.WriteLine("The wall shifts position..."); for (int y = 0; y < 8; y++) if (random.NextDouble() > 0.5 && edge[y] > 1) wall[edge[y] - 1, y] = 0; UpdateEdgePositions(); } }
Console.WriteLine("Game over - you've been turned to stone!"); }
static void Main() { new WizardsWall().Play(); }}Python
import mathimport randomimport os
class WizardsWall: def __init__(self): self.wall = [[20 for _ in range(8)] for _ in range(8)] self.edge = [0] * 8 self.game_over = False
def clear_screen(self): os.system('cls' if os.name == 'nt' else 'clear')
def show_help(self): help_text = [ "You are attacking the last stronghold of the notorious wizard, who is", "hidden behind an endless stone wall. Each stone is one of his former", "victims. Only you can attack and free them from his magic.", "", "You must destroy the wall using catapults. But beware, the wizard has", "the power to move the wall back and forth, and occasionally to deflect", "your shots back at you.", "", "After each shot, you'll see a cross-section of the wall showing damage.", "Note there are certain key stones that produce lots of damage. Also,", "the faster the boulder moves horizontally, the more damage it causes.", "", "Can you defeat the wizard in time to save the thousands of trapped souls?" ] for line in help_text: print(line) input("\nPress Enter to continue...")
def display_wall(self): print() for y in range(7, -1, -1): for x in range(8): char = '□' if self.wall[x][y] == 20 else ' ' print(char, end='') print()
def update_edge_positions(self): self.game_over = False for y in range(8): x = 0 while x < 8 and self.wall[x][y] != 0: x += 1 self.edge[y] = x if x == 1: self.game_over = True
def damage_wall(self, height, speed, angle): if not (0 <= height - 1 < 8): return
horiz_velocity = speed * math.cos(math.radians(angle)) edge_pos = self.edge[height - 1]
if edge_pos > 0: self.wall[edge_pos - 1][height - 1] = 0
if horiz_velocity > 50 and edge_pos > 1: self.wall[edge_pos - 2][height - 1] = 0
if random.random() > 0.5 and height < 7: if self.edge[height] > 0: self.wall[self.edge[height] - 1][height] = 0
self.update_edge_positions()
def play(self): self.clear_screen() print("Wizard's Wall")
if input("Would you like help? (y/n): ").upper().startswith('Y'): self.show_help()
difficulty = int(input("Select difficulty (1-5): ")) scale_factor = 6 - difficulty
for round in range(3): if self.game_over: print("Victory! You've broken through the wall and freed the victims.") return
distance = random.randint(21, 40) wind = random.randint(-20, 20)
self.display_wall() print(f"You are {distance} yards away")
if wind == 0: print("No wind") elif wind < 0: print("Wind to right") else: print("Wind to left")
angle = float(input("Enter elevation (1-90): ")) speed = float(input("Enter speed: "))
height = math.tan(math.radians(angle)) * distance height -= (5 * (distance - wind)**2) / (speed * math.cos(math.radians(angle)))**2 height = int(height / scale_factor)
if 1 <= height <= 8: if random.random() > 0.2: self.damage_wall(height, speed, angle) else: print("The wizard deflected your shot!") elif height < 1: print("Shot was too near") else: print("Shot was too far")
if random.random() > 0.2: print("The wall shifts position...") for y in range(8): if random.random() > 0.5 and self.edge[y] > 1: self.wall[self.edge[y] - 1][y] = 0 self.update_edge_positions()
print("Game over - you've been turned to stone!")
if __name__ == "__main__": game = WizardsWall() game.play()Java
import java.util.Random;import java.util.Scanner;
public class WizardsWall { private final int[][] wall = new int[8][8]; private final int[] edge = new int[8]; private boolean gameOver = false; private final Random random = new Random(); private final Scanner scanner = new Scanner(System.in);
private void showHelp() { String[] help = { "You are attacking the last stronghold of the notorious wizard, who is", "hidden behind an endless stone wall. Each stone is one of his former", "victims. Only you can attack and free them from his magic.", "", "You must destroy the wall using catapults. But beware, the wizard has", "the power to move the wall back and forth, and occasionally to deflect", "your shots back at you.", "", "After each shot, you'll see a cross-section of the wall showing damage.", "Note there are certain key stones that produce lots of damage. Also,", "the faster the boulder moves horizontally, the more damage it causes.", "", "Can you defeat the wizard in time to save the thousands of trapped souls?" }; for (String line : help) System.out.println(line); System.out.println("\nPress Enter to continue..."); scanner.nextLine(); }
private void displayWall() { System.out.println(); for (int y = 7; y >= 0; y--) { for (int x = 0; x < 8; x++) { System.out.print(wall[x][y] == 20 ? "□" : " "); } System.out.println(); } }
private void updateEdgePositions() { gameOver = false; for (int y = 0; y < 8; y++) { int x = 0; while (x < 8 && wall[x][y] == 20) x++; edge[y] = x; if (x == 1) gameOver = true; } }
private void damageWall(int height, double speed, double angle) { if (!(0 <= height - 1 && height - 1 < 8)) return;
double horizVelocity = speed * Math.cos(Math.toRadians(angle)); int edgePos = edge[height - 1];
if (edgePos > 0) wall[edgePos - 1][height - 1] = 0;
if (horizVelocity > 50 && edgePos > 1) wall[edgePos - 2][height - 1] = 0;
if (random.nextDouble() > 0.5 && height < 7) if (edge[height] > 0) wall[edge[height] - 1][height] = 0;
updateEdgePositions(); }
public void play() { System.out.println("Wizard's Wall"); System.out.print("Would you like help? (y/n): ");
if (scanner.nextLine().trim().toUpperCase().startsWith("Y")) showHelp();
System.out.print("Select difficulty (1-5): "); int difficulty = Integer.parseInt(scanner.nextLine()); int scaleFactor = 6 - difficulty;
for (int y = 0; y < 8; y++) for (int x = 0; x < 8; x++) wall[x][y] = 20;
for (int round = 0; round < 3; round++) { if (gameOver) { System.out.println("Victory! You've broken through the wall and freed the victims."); return; }
int distance = random.nextInt(20) + 21; int wind = random.nextInt(41) - 20;
displayWall(); System.out.println("You are " + distance + " yards away");
if (wind == 0) System.out.println("No wind"); else System.out.println(wind < 0 ? "Wind to right" : "Wind to left");
System.out.print("Enter elevation (1-90): "); double angle = Double.parseDouble(scanner.nextLine()); System.out.print("Enter speed: "); double speed = Double.parseDouble(scanner.nextLine());
double height = Math.tan(Math.toRadians(angle)) * distance - (5 * Math.pow(distance - wind, 2)) / Math.pow(speed * Math.cos(Math.toRadians(angle)), 2); height = Math.floor(height / scaleFactor);
if (height >= 1 && height <= 8) { if (random.nextDouble() > 0.2) { damageWall((int)height, speed, angle); } else { System.out.println("The wizard deflected your shot!"); } } else { System.out.println(height < 1 ? "Shot was too near" : "Shot was too far"); }
if (random.nextDouble() > 0.2) { System.out.println("The wall shifts position..."); for (int y = 0; y < 8; y++) if (random.nextDouble() > 0.5 && edge[y] > 1) wall[edge[y] - 1][y] = 0; updateEdgePositions(); } }
System.out.println("Game over - you've been turned to stone!"); scanner.close(); }
public static void main(String[] args) { new WizardsWall().play(); }}Go
package main
import ( "bufio" "fmt" "math" "math/rand" "os" "strconv" "strings" "time")
type WizardsWall struct { wall [8][8]int edge [8]int gameOver bool}
func (w *WizardsWall) showHelp() { help := []string{ "You are attacking the last stronghold of the notorious wizard, who is", "hidden behind an endless stone wall. Each stone is one of his former", "victims. Only you can attack and free them from his magic.", "", "You must destroy the wall using catapults. But beware, the wizard has", "the power to move the wall back and forth, and occasionally to deflect", "your shots back at you.", "", "After each shot, you'll see a cross-section of the wall showing damage.", "Note there are certain key stones that produce lots of damage. Also,", "the faster the boulder moves horizontally, the more damage it causes.", "", "Can you defeat the wizard in time to save the thousands of trapped souls?", } for _, line := range help { fmt.Println(line) } fmt.Print("\nPress Enter to continue...") bufio.NewReader(os.Stdin).ReadBytes('\n')}
func (w *WizardsWall) displayWall() { fmt.Println() for y := 7; y >= 0; y-- { for x := 0; x < 8; x++ { if w.wall[x][y] == 20 { fmt.Print("□") } else { fmt.Print(" ") } } fmt.Println() }}
func (w *WizardsWall) updateEdgePositions() { w.gameOver = false for y := 0; y < 8; y++ { x := 0 for x < 8 && w.wall[x][y] == 20 { x++ } w.edge[y] = x if x == 1 { w.gameOver = true } }}
func (w *WizardsWall) damageWall(height int, speed, angle float64) { if height-1 < 0 || height-1 >= 8 { return }
horizVelocity := speed * math.Cos(angle*math.Pi/180.0) edgePos := w.edge[height-1]
if edgePos > 0 { w.wall[edgePos-1][height-1] = 0 }
if horizVelocity > 50 && edgePos > 1 { w.wall[edgePos-2][height-1] = 0 }
if rand.Float64() > 0.5 && height < 7 { if w.edge[height] > 0 { w.wall[w.edge[height]-1][height] = 0 } }
w.updateEdgePositions()}
func (w *WizardsWall) play() { reader := bufio.NewReader(os.Stdin) fmt.Println("Wizard's Wall") fmt.Print("Would you like help? (y/n): ")
response, _ := reader.ReadString('\n') if strings.ToLower(strings.TrimSpace(response))[0] == 'y' { w.showHelp() }
fmt.Print("Select difficulty (1-5): ") diffStr, _ := reader.ReadString('\n') difficulty, _ := strconv.Atoi(strings.TrimSpace(diffStr)) scaleFactor := 6 - difficulty
// Initialize wall for y := 0; y < 8; y++ { for x := 0; x < 8; x++ { w.wall[x][y] = 20 } }
for round := 0; round < 3; round++ { if w.gameOver { fmt.Println("Victory! You've broken through the wall and freed the victims.") return }
distance := rand.Intn(20) + 21 wind := rand.Intn(41) - 20
w.displayWall() fmt.Printf("You are %d yards away\n", distance)
if wind == 0 { fmt.Println("No wind") } else if wind < 0 { fmt.Println("Wind to right") } else { fmt.Println("Wind to left") }
fmt.Print("Enter elevation (1-90): ") angleStr, _ := reader.ReadString('\n') angle, _ := strconv.ParseFloat(strings.TrimSpace(angleStr), 64)
fmt.Print("Enter speed: ") speedStr, _ := reader.ReadString('\n') speed, _ := strconv.ParseFloat(strings.TrimSpace(speedStr), 64)
height := math.Tan(angle*math.Pi/180.0)*float64(distance) - (5*math.Pow(float64(distance-wind), 2))/ math.Pow(speed*math.Cos(angle*math.Pi/180.0), 2) height = math.Floor(height / float64(scaleFactor))
if height >= 1 && height <= 8 { if rand.Float64() > 0.2 { w.damageWall(int(height), speed, angle) } else { fmt.Println("The wizard deflected your shot!") } } else { if height < 1 { fmt.Println("Shot was too near") } else { fmt.Println("Shot was too far") } }
if rand.Float64() > 0.2 { fmt.Println("The wall shifts position...") for y := 0; y < 8; y++ { if rand.Float64() > 0.5 && w.edge[y] > 1 { w.wall[w.edge[y]-1][y] = 0 } } w.updateEdgePositions() } }
fmt.Println("Game over - you've been turned to stone!")}
func main() { rand.Seed(time.Now().UnixNano()) game := &WizardsWall{} game.play()}C++
#include <iostream>#include <cmath>#include <random>#include <string>#include <vector>
class WizardsWall {private: int wall[8][8]; int edge[8]; bool gameOver = false; std::random_device rd; std::mt19937 gen{rd()};
void showHelp() { const std::vector<std::string> help = { "You are attacking the last stronghold of the notorious wizard, who is", "hidden behind an endless stone wall. Each stone is one of his former", "victims. Only you can attack and free them from his magic.", "", "You must destroy the wall using catapults. But beware, the wizard has", "the power to move the wall back and forth, and occasionally to deflect", "your shots back at you.", "", "After each shot, you'll see a cross-section of the wall showing damage.", "Note there are certain key stones that produce lots of damage. Also,", "the faster the boulder moves horizontally, the more damage it causes.", "", "Can you defeat the wizard in time to save the thousands of trapped souls?" }; for (const auto& line : help) std::cout << line << '\n'; std::cout << "\nPress Enter to continue..."; std::cin.get(); }
void displayWall() { std::cout << '\n'; for (int y = 7; y >= 0; --y) { for (int x = 0; x < 8; ++x) { std::cout << (wall[x][y] == 20 ? "□" : " "); } std::cout << '\n'; } }
void updateEdgePositions() { gameOver = false; for (int y = 0; y < 8; ++y) { int x = 0; while (x < 8 && wall[x][y] == 20) ++x; edge[y] = x; if (x == 1) gameOver = true; } }
void damageWall(int height, double speed, double angle) { if (!(0 <= height - 1 && height - 1 < 8)) return;
double horizVelocity = speed * cos(angle * M_PI / 180.0); int edgePos = edge[height - 1];
if (edgePos > 0) wall[edgePos - 1][height - 1] = 0;
if (horizVelocity > 50 && edgePos > 1) wall[edgePos - 2][height - 1] = 0;
std::uniform_real_distribution<> dis(0, 1); if (dis(gen) > 0.5 && height < 7) if (edge[height] > 0) wall[edge[height] - 1][height] = 0;
updateEdgePositions(); }
public: WizardsWall() { for (int y = 0; y < 8; ++y) for (int x = 0; x < 8; ++x) wall[x][y] = 20; }
void play() { std::cout << "Wizard's Wall\n"; std::cout << "Would you like help? (y/n): ";
std::string response; std::getline(std::cin, response); if (response[0] == 'y' || response[0] == 'Y') showHelp();
std::cout << "Select difficulty (1-5): "; int difficulty; std::cin >> difficulty; int scaleFactor = 6 - difficulty;
std::uniform_real_distribution<> dis(0, 1); std::uniform_int_distribution<> distDist(21, 40); std::uniform_int_distribution<> windDist(-20, 20);
for (int round = 0; round < 3; ++round) { if (gameOver) { std::cout << "Victory! You've broken through the wall and freed the victims.\n"; return; }
int distance = distDist(gen); int wind = windDist(gen);
displayWall(); std::cout << "You are " << distance << " yards away\n";
if (wind == 0) std::cout << "No wind\n"; else std::cout << (wind < 0 ? "Wind to right\n" : "Wind to left\n");
double angle, speed; std::cout << "Enter elevation (1-90): "; std::cin >> angle; std::cout << "Enter speed: "; std::cin >> speed;
double height = tan(angle * M_PI / 180.0) * distance - (5 * pow(distance - wind, 2)) / pow(speed * cos(angle * M_PI / 180.0), 2); height = floor(height / scaleFactor);
if (height >= 1 && height <= 8) { if (dis(gen) > 0.2) { damageWall(static_cast<int>(height), speed, angle); } else { std::cout << "The wizard deflected your shot!\n"; } } else { std::cout << (height < 1 ? "Shot was too near\n" : "Shot was too far\n"); }
if (dis(gen) > 0.2) { std::cout << "The wall shifts position...\n"; for (int y = 0; y < 8; ++y) if (dis(gen) > 0.5 && edge[y] > 1) wall[edge[y] - 1][y] = 0; updateEdgePositions(); } }
std::cout << "Game over - you've been turned to stone!\n"; }};
int main() { WizardsWall game; game.play(); return 0;}Explanation
The Wizard’s Wall game requires the player to destroy an enchanted wall by firing boulders at specific angles and speeds. Each turn, the wall’s state is displayed, and the player inputs their shot’s trajectory. If the shot is successful, a part of the wall is destroyed. If it misses, the Wizard’s magic deflects the shot. The game ends when the wall is entirely destroyed (victory) or if the player runs out of turns (failure).
Challenges
- Wall Variations: Add thicker walls or multiple layers to increase difficulty.
- Advanced Deflection: Introduce moving deflection zones that require precise timing to avoid.
- Power-ups: Include items like explosive boulders or shields to improve player strategy.
- Time Pressure: Implement a timer for each turn to raise the stakes.
- Custom Modes: Allow players to design their own wall layouts for more personalized challenges.
Copyright
These programs are adaptations of the original Usborne Computer Guides published in the 1980s. The books are free to download for personal or educational use from Usborne’s Computer and Coding Books. Programs and adaptations may not be used for commercial purposes.
Return to Computer Battlegames.