mirror of
https://github.com/coding-horror/basic-computer-games.git
synced 2025-12-25 04:15:45 -08:00
Added go version of Bombs_Away
This commit is contained in:
188
00_Alternate_Languages/12_Bombs_Away/go/main.go
Normal file
188
00_Alternate_Languages/12_Bombs_Away/go/main.go
Normal file
@@ -0,0 +1,188 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
type Choice struct {
|
||||
idx string
|
||||
msg string
|
||||
}
|
||||
|
||||
func playerSurvived() {
|
||||
fmt.Println("YOU MADE IT THROUGH TREMENDOUS FLAK!!")
|
||||
}
|
||||
|
||||
func playerDeath() {
|
||||
fmt.Println("* * * * BOOM * * * *")
|
||||
fmt.Println("YOU HAVE BEEN SHOT DOWN.....")
|
||||
fmt.Println("DEARLY BELOVED, WE ARE GATHERED HERE TODAY TO PAY OUR")
|
||||
fmt.Println("LAST TRIBUTE...")
|
||||
}
|
||||
|
||||
func missionSuccess() {
|
||||
fmt.Printf("DIRECT HIT!!!! %d KILLED.\n", int(100*rand.Int()))
|
||||
fmt.Println("MISSION SUCCESSFUL.")
|
||||
}
|
||||
|
||||
// Takes a float between 0 and 1 and returns a boolean
|
||||
// if the player has survived (based on random chance)
|
||||
// Returns True if death, False if survived
|
||||
func deathWithChance(probability float64) bool {
|
||||
return probability > rand.Float64()
|
||||
}
|
||||
|
||||
func startNonKamikaziAttack() {
|
||||
numMissions := getIntInput("HOW MANY MISSIONS HAVE YOU FLOWN? ")
|
||||
|
||||
for numMissions > 160 {
|
||||
fmt.Println("MISSIONS, NOT MILES...")
|
||||
fmt.Println("150 MISSIONS IS HIGH EVEN FOR OLD-TIMERS")
|
||||
numMissions = getIntInput("HOW MANY MISSIONS HAVE YOU FLOWN? ")
|
||||
}
|
||||
|
||||
if numMissions > 100 {
|
||||
fmt.Println("THAT'S PUSHING THE ODDS!")
|
||||
}
|
||||
|
||||
if numMissions < 25 {
|
||||
fmt.Println("FRESH OUT OF TRAINING, EH?")
|
||||
}
|
||||
|
||||
fmt.Println()
|
||||
|
||||
if float32(numMissions) > (160 * rand.Float32()) {
|
||||
missionSuccess()
|
||||
} else {
|
||||
missionFailure()
|
||||
}
|
||||
}
|
||||
|
||||
func missionFailure() {
|
||||
fmt.Printf("MISSED TARGET BY %d MILES!\n", int(2+30*rand.Float32()))
|
||||
fmt.Println("NOW YOU'RE REALLY IN FOR IT !!")
|
||||
fmt.Println()
|
||||
|
||||
enemyWeapons := getInputFromList("DOES THE ENEMY HAVE GUNS(1), MISSILES(2), OR BOTH(3)? ", []Choice{{idx: "1", msg: "GUNS"}, {idx: "2", msg: "MISSILES"}, {idx: "3", msg: "BOTH"}})
|
||||
|
||||
// If there are no gunners (i.e. weapon choice 2) then
|
||||
// we say that the gunners have 0 accuracy for the purposes
|
||||
// of calculating probability of player death
|
||||
enemyGunnerAccuracy := 0.0
|
||||
if enemyWeapons.idx != "2" {
|
||||
enemyGunnerAccuracy = float64(getIntInput("WHAT'S THE PERCENT HIT RATE OF ENEMY GUNNERS (10 TO 50)? "))
|
||||
if enemyGunnerAccuracy < 10.0 {
|
||||
fmt.Println("YOU LIE, BUT YOU'LL PAY...")
|
||||
playerDeath()
|
||||
}
|
||||
}
|
||||
|
||||
missileThreatWeighting := 35.0
|
||||
if enemyWeapons.idx == "1" {
|
||||
missileThreatWeighting = 0
|
||||
}
|
||||
|
||||
death := deathWithChance((enemyGunnerAccuracy + missileThreatWeighting) / 100)
|
||||
|
||||
if death {
|
||||
playerDeath()
|
||||
} else {
|
||||
playerSurvived()
|
||||
}
|
||||
}
|
||||
|
||||
func playItaly() {
|
||||
targets := []Choice{{idx: "1", msg: "SHOULD BE EASY -- YOU'RE FLYING A NAZI-MADE PLANE."}, {idx: "2", msg: "BE CAREFUL!!!"}, {idx: "3", msg: "YOU'RE GOING FOR THE OIL, EH?"}}
|
||||
target := getInputFromList("YOUR TARGET -- ALBANIA(1), GREECE(2), NORTH AFRICA(3)", targets)
|
||||
fmt.Println(target.msg)
|
||||
startNonKamikaziAttack()
|
||||
}
|
||||
|
||||
func playAllies() {
|
||||
aircraftMessages := []Choice{{idx: "1", msg: "YOU'VE GOT 2 TONS OF BOMBS FLYING FOR PLOESTI."}, {idx: "2", msg: "YOU'RE DUMPING THE A-BOMB ON HIROSHIMA."}, {idx: "3", msg: "YOU'RE CHASING THE BISMARK IN THE NORTH SEA."}, {idx: "4", msg: "YOU'RE BUSTING A GERMAN HEAVY WATER PLANT IN THE RUHR."}}
|
||||
aircraft := getInputFromList("AIRCRAFT -- LIBERATOR(1), B-29(2), B-17(3), LANCASTER(4): ", aircraftMessages)
|
||||
fmt.Println(aircraft.msg)
|
||||
startNonKamikaziAttack()
|
||||
}
|
||||
|
||||
func playJapan() {
|
||||
acknowledgeMessage := []Choice{{idx: "Y", msg: "Y"}, {idx: "N", msg: "N"}}
|
||||
firstMission := getInputFromList("YOU'RE FLYING A KAMIKAZE MISSION OVER THE USS LEXINGTON.\nYOUR FIRST KAMIKAZE MISSION? (Y OR N): ", acknowledgeMessage)
|
||||
if firstMission.msg == "N" {
|
||||
playerDeath()
|
||||
}
|
||||
if rand.Float64() > 0.65 {
|
||||
missionSuccess()
|
||||
} else {
|
||||
playerDeath()
|
||||
}
|
||||
}
|
||||
|
||||
func playGermany() {
|
||||
targets := []Choice{{idx: "1", msg: "YOU'RE NEARING STALINGRAD."}, {idx: "2", msg: "NEARING LONDON. BE CAREFUL, THEY'VE GOT RADAR."}, {idx: "3", msg: "NEARING VERSAILLES. DUCK SOUP. THEY'RE NEARLY DEFENSELESS."}}
|
||||
target := getInputFromList("A NAZI, EH? OH WELL. ARE YOU GOING FOR RUSSIA(1),\nENGLAND(2), OR FRANCE(3)? ", targets)
|
||||
fmt.Println(target.msg)
|
||||
startNonKamikaziAttack()
|
||||
}
|
||||
|
||||
func playGame() {
|
||||
fmt.Println("YOU ARE A PILOT IN A WORLD WAR II BOMBER.")
|
||||
side := getInputFromList("WHAT SIDE -- ITALY(1), ALLIES(2), JAPAN(3), GERMANY(4): ", []Choice{{idx: "1", msg: "ITALY"}, {idx: "2", msg: "ALLIES"}, {idx: "3", msg: "JAPAN"}, {idx: "4", msg: "GERMANY"}})
|
||||
switch side.idx {
|
||||
case "1":
|
||||
playItaly()
|
||||
case "2":
|
||||
playAllies()
|
||||
case "3":
|
||||
playJapan()
|
||||
case "4":
|
||||
playGermany()
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
rand.Seed(time.Now().UnixNano())
|
||||
|
||||
for {
|
||||
playGame()
|
||||
if getInputFromList("ANOTHER MISSION (Y OR N):", []Choice{{idx: "Y", msg: "Y"}, {idx: "N", msg: "N"}}).msg == "N" {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func getInputFromList(prompt string, choices []Choice) Choice {
|
||||
scanner := bufio.NewScanner(os.Stdin)
|
||||
for {
|
||||
fmt.Println(prompt)
|
||||
scanner.Scan()
|
||||
choice := scanner.Text()
|
||||
for _, c := range choices {
|
||||
if strings.EqualFold(strings.ToUpper(choice), strings.ToUpper(c.idx)) {
|
||||
return c
|
||||
}
|
||||
}
|
||||
fmt.Println("TRY AGAIN...")
|
||||
}
|
||||
}
|
||||
|
||||
func getIntInput(prompt string) int {
|
||||
scanner := bufio.NewScanner(os.Stdin)
|
||||
for {
|
||||
fmt.Println(prompt)
|
||||
scanner.Scan()
|
||||
choice, err := strconv.Atoi(scanner.Text())
|
||||
if err != nil {
|
||||
fmt.Println("TRY AGAIN...")
|
||||
continue
|
||||
} else {
|
||||
return choice
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user