Help us understand the problem. What is going on with this article?

Golangの勉強がてら、Console上で動く簡易なゲームを作った

More than 1 year has passed since last update.

経緯

ある雨の日
(^.^):「Go?あーPokemon GOはもうやってないんだよなー。」
(?_?):「え?Pokemon GOじゃないって?Golang?!」
('Д'):「なにそれ?おいしいの?」
(=_=):「?!それ使ってXXX作らなくちゃいけないの?」
(*_*):「まずは勉強しなくちゃ…」

作ったもの

Console上で動くバトルアプリ?ゲーム?を作りました(学習がてら)。
(当時ヒーローアカデミアにはまってた)
ヒーローのSkillを上手いこと定義すれば、二人のHeroがいい感じの勝負をします。
定義のポイントとしては、speedを高く設定すると攻撃を避けやすくなります。
2018-12-04_22h01_02_Trim.gif

設定ファイルを用いないver

https://play.golang.org/p/nkVi7stskxf

設定ファイルを用いたver

HeroBattle
 ┣ HeroConfig.toml
 ┗ main.go

HeroConfig.toml
# 【制約】3値が全て0以上かつ、power + speed + hp が100を超えてはいけない
[hero1]
name  = "パワー系"
power = 50
speed = 15
hp    = 35
[hero2]
name  = "スピード系"
power = 15
speed = 50
hp    = 35
main.go
package main

import (
    "fmt"
    "github.com/BurntSushi/toml"
    "github.com/shiena/ansicolor"
    "math"
    "math/rand"
    "os"
    "time"
)

//ヒーロー(インターフェース)
type Hero interface {
    Attack() int
    Defense(int) int
}

//能力(構造体)
type HeroConfig struct {
    Hero1 Skill
    Hero2 Skill
}

type Skill struct {
    Name  string
    Power int
    Speed int
    Hp    int
}

//攻撃(メソッド)・・・パワーで攻撃力が決定する
func (u *Skill) Attack() int {
    rand.Seed(time.Now().UnixNano())

    if 0 == rand.Intn(10) {
        fmt.Printf("クリティカル!\r\n\r\n")
        time.Sleep(3000 * time.Millisecond)
        fmt.Printf("(*`Д´)=Э)TДT●)\r\n\r\n")
        return int(math.Sqrt(float64(u.Power))) * 2
    } else {
        return int(math.Sqrt(float64(u.Power)))
    }
}

//回避・ダメージ(メソッド)・・・Speedが速ければ、攻撃を回避しやすい
func (u *Skill) Defense(damage int) int {
    rand.Seed(time.Now().UnixNano())
    if u.Speed > rand.Intn(100) {
        fmt.Printf("回避成功\r\n\r\n")
        return u.Hp //回避成功
    } else {
        fmt.Printf("%dのダメージ\r\n\r\n", damage)
        u.Hp = u.Hp - damage
        return u.Hp //回避失敗
    }
}

//バトル(関数)
func Battle(hero1_info *Skill, hero2_info *Skill) {
    at := hero1_info
    df := hero2_info
    var AT Hero = hero1_info
    var DF Hero = hero2_info
    turn := 1
    for {
        fmt.Printf("%dラウンド-------------------------------\r\n", turn)
        fmt.Printf("【HP:%d】%s VS 【HP:%d】%s\r\n\r\n", at.Hp, at.Name, df.Hp, df.Name)
        fmt.Printf("%sの攻撃\r\n\r\n", at.Name)
        if DF.Defense(AT.Attack()) <= 0 {
            for i := 0; i < 5; i++ {
                fmt.Println("  ・")
                time.Sleep(500 * time.Millisecond)
            }
            fmt.Printf("【HP:%d】%sは力尽きた・・・。【HP:%d】%sの勝利!!!\r\n\r\n", df.Hp, df.Name, at.Hp, at.Name)
            return
        }
        time.Sleep(1000 * time.Millisecond)
        //攻守交換
        temp := at
        at = df
        df = temp
        TEMP := AT
        AT = DF
        DF = TEMP
        turn++
    }
}

//能力の上限チェック(関数) 第三引数のlimitよりもPower+Speed+Hpが上回ってはいけない
func SkillCheck(hero1 *Skill, hero2 *Skill, limit int) bool {
    check1 := hero1.Power + hero1.Speed + hero1.Hp
    check2 := hero2.Power + hero2.Speed + hero2.Hp
    fmt.Printf("limit:%d\r\n", limit)
    fmt.Printf("〇先行:%s\r\nPower:%d\r\nSpeed:%d\r\nHp   :%d\r\nSum  :%d\r\n\r\n", hero1.Name, hero1.Power, hero1.Speed, hero1.Hp, check1)
    fmt.Printf("△後攻:%s\r\nPower:%d\r\nSpeed:%d\r\nHp   :%d\r\nSum  :%d\r\n\r\n", hero2.Name, hero2.Power, hero2.Speed, hero2.Hp, check2)
    if check1 <= limit && check2 <= limit && hero1.Power > 0 && hero1.Speed > 0 && hero1.Hp > 0 && hero2.Power > 0 && hero2.Speed > 0 && hero2.Hp > 0 {
        return true
    } else {
        return false
    }
}

func main() {
    w := ansicolor.NewAnsiColorWriter(os.Stdout)
    // tomlファイルから情報を読み取る
    var hero HeroConfig
    _, err := toml.DecodeFile("HeroConfig.toml", &hero)
    if err != nil {
        panic(err)
    }
    // バトル開始 能力の上限値は100 能力の上限を超えていればバトルは行われない。
    if SkillCheck(&hero.Hero1, &hero.Hero2, 100) == true {
        Battle(&hero.Hero1, &hero.Hero2)
    } else {
        fmt.Printf("バトル開始不可能")
    }
    fmt.Fprintf(w, "\r\n%s SUCCESS!!!%s", "\x1b[33m\x1b[1m", "\x1b[22m\x1b[0m")
}

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした