Newer
Older
Ruby / RPG.rb
@TOGASHI Yuto TOGASHI Yuto on 26 Nov 2021 20 KB 2021-11-26 14:56:42
#!/usr/bin/env ruby
# -*- coding: utf-8 -*-

#変数名の最初は大文字NG

ability = [20,3,8,5,5,20,15,1]  #能力値最大
#HP(0体力)MP(1魔力)ATS(2攻撃力)MAT(3魔法攻撃力)DEF(4防御力)DEX(5素早さ)AGI(6器用さ)LUK(7運)

current = [20,3]  #現在の能力値
#現在のHPとMP

lv = [1,0,0]                      #レベル関連 
#Lv(レベル)EXP(経験値)

lvup = [0,8]

g = [30]                           #お金(Gold)

count = [0,0,0,0] #0=バトル数1=勝利数2=敗北数3=逃走数

progress = 0                    #ストーリーの進行度

gamedescription = ["ゲーム説明","このゲームはメニューで行動を選択して遊びます",
                   "ステータスを見る・宿屋へ行く・武器屋へ行く・教会へ行く・探索へ行くの中から好きなのを選びます",
                   "ステータスを見るは今の自分のステータスを見ることができます",
                   "HP=体力 MP=魔力・魔法防御力 ATS=攻撃力 MAT=魔法攻撃力 DEF=防御力 DEX=素早さ AGI=器用さ  LUK=運",
                   "宿屋はGを支払うとHP・MPが回復します",
                   "武器屋は武器・防具を購入することができます",
                   "教会はセーブをすることができます",
                   "探索は魔物の生息地に行き 戦いをします",
                   "戦いは行動を選択して魔物を倒します",
                   "死んでしまったら'GAMEOVER'でGを失い村・街からやり直しです",
                   "目標は魔王を倒すこと!",
                   "じゃぁクリア目指して頑張ってね",
                   "※このゲームは共同制作作品です"]
#ゲーム説明

prorogu = ["\e[96m_me_:う、うっ",
           "\e[96;2m(強い頭痛を感じ_jibun_は意識を失った)",
           "\e[96;2m(目覚めると そこは見知らぬ村だった)",
           "\e[96m_me_:こ、ここは どこ?",
           "\e[96;2m(その瞬間すべてを思い出した)",
           "\e[96;2m(剣術や魔法 世界のことわり)",
           "\e[96;2m(そして魔王を倒さなければ ならないという強い使命感を覚えた)",
           "\e[96m_me_:魔王を倒さなければ",
           "\e[96m_me_:なぜだか わからないけど そんな気がする",
           "\e[96m_me_:あっ そして ここは どこなんだろう",
           "(近くに村人らしき人が見える)",
           "\e[96m_me_:すみません ここが どこか わかりますか",
           "\e[2m村人:何いってるんだい?",
           "\e[2m村人:ここは「パクス村」ディーヴァス川のほとりにある小さな農村さ",
           "\e[2m村人:ここが初めてなら注意しておくけど「ポルタ平原」には魔物が出るから用意なしには行くなよ",
           "\e[2m村人:まぁ旅人なら宿屋で休んでいきな",
           "\e[96m_me_:あっ _jibun_ お金持ってないんですけど",
           "\e[2m村人:なんだお前さん一文無しかよ",
           "\e[2m村人:しかたねーなー ここで会ったのも何かの縁だ",
           "\e[2m村人:30Gやるから あとは魔物でも倒して自分で稼げ",
           "(_me_は村人から30Gをもらった)",
           "\e[2m村人:じゃぁな",
           "\e[96m_me_:とりあえずポルタ平原を探索しようかな"]
#最初の会話シーン
#\e[○mは色を変えるコマンド
#_me_などはPLの名前などに置き換える

credit = ["スタッフロール(クレジットタイトル)","システム","村井侑平 澤田羽衣",
          "システムアドバイザー","佐藤隆之助 阿部光峻",
          "広瀬雄二様 東北公益文科大学の皆様",
          "シナリオ","村井侑平 高橋真翔 佐藤風斗 佐藤然",
          "シナリオアドバイザー","佐藤隆之助 澤田羽衣 疋田琉莉 阿部光峻",
          "グラフィック","村井侑平",          "この作品に関わった すべての方に感謝の意を申し上げます",
          "制作","「#みんなでゲームを作ろう」の会"]
#クレジットタイトル(スタッフロール)

battleselect = ["攻撃","アイテム","逃げる"]
#バトルの行動の選択肢

attack = ["スラッシュ"]         #攻撃名
attackdetail = [[1,0,0]]        #攻撃の詳細

monster = ["スライム","デーモンビースト","黒い影","\e[93mゴールデンスライム"] #モンスター名

enemy = [[12,12,8,8,4,0,3,10,8,1,3,"突進","Error"],[15,15,5,5,10,0,5,25,15,1,7,"突進","Error"],
         [8,8,15,15,0,8,20,35,25,3,13,"Error","闇の刃"],[12,12,20,20,6,0,30,8,8,1,30,"突進","Error"]]
#モンスターの能力値

kakuritu = [0]*91 + [1]*5 + [2]*3 + [3]*1,[0]*82 + [1]*10 + [2]*5 + [3]*3,[0]*72 + [1]*15 + [2]*8 + [3]*5,[0]*52 + [1]*25 + [2]*15 + [3]*8,[0]*25 + [1]*40 + [2]*25 + [3]*10
#モンスターの出現確率

status = []                     #PLが入力する[名前、性別、一人称etc.]

item = []                       #アイテム

area = []                       #探索に行けるエリア

searchselect = ["深部に進む","拠点に戻る"]

sentaku = ["プレイ","ゲーム説明","クレジットタイトル"]

q1 = ["男","女"]                #性別
q2 = ["俺","僕","私"]           #一人称
#キャラ設定の選択肢

nani = [["名前","性別","一人称"],["Lv","EXP"],["HP","MP"],["ATS","MAT","DEF","DEX","AGI","LUK"],
        ["ステータスを見る","宿屋に行く","武器屋に行く","教会に行く","探索に行く"]]

yadoya = ["泊まる10G","泊まらない"]
kyokai = ["祈りを捧げる(セーブ)","聖水を買う(20G)"]
bukiya = ["石剣10G ATS+1","買わない"]
#各施設の選択肢

def status(status,ability,current,nani,lv,g) #ステータスを表示するためのメソッド
  x = 0
  puts"               ステータス"
  for i in nani[0]    #i = ["名前","性別","一人称"]
    printf("%s:%s   ",i,status[x])  #名前性別一人称
    x += 1
  end
  x = 0
  printf("Lv.%s   ",lv[0])
  printf("EXP:%d   ",lv[1])
  printf("所持金:%dG",g[0])
  print("\n")
  for i in nani[2]
    printf("%s:%d/%d   ",i,ability[x],current[x])
    x += 1
  end
  x = 2
  for i in nani[3]
    printf("%s:%d   ",i,ability[x])
    x += 1
  end
  print("\n\n")
end

def question(situmon,list)                 #質問を出すメソッド
  kaisu = 0
  select = -1
  while kaisu < list.length
    printf("%s(%d)\n",list[kaisu],kaisu)
    print("\e[m")
    kaisu += 1
  end
  while select < 0 || select >= list.length   #回答の仕分け
    print(situmon+":")
    select = gets
    if select == "\n"
      redo
    end
    select = select.to_i
  end
  return list[select]           #ただ見やすくしてる
end

def query(situmon,list)                 #質問を出すメソッド
  kaisu = 0
  select = -1
  while kaisu < list.length
    printf("%s(%d)\n",list[kaisu],kaisu)
    print("\e[m")
    kaisu += 1
  end
  while select < 0 || select >= list.length   #回答の仕分け
    print(situmon+":")
    select = gets
    if select == "\n"
      redo
    end
    select = select.to_i
  end
  return select          #数字版
end

def dot(time,kaisu,ten)   #「.」のためにいろいろ打ちたくなかったのメソッド
  for i in 1..kaisu
    sleep(time)
    print(ten)
  end
end

def description(hanasi)         #会話を出すためのメソッド
  for i in hanasi
    puts(i)
    print("\e[m")
    gets
  end
end

def story(hanasi,status)             #物語のgetsをサボりたいのメソッド
  for i in hanasi
    puts(i.sub("_me_", status[0])               #subがiのキーワードを 
    	   .sub("_jibun_", status[2])       #特定の文字に
	   .sub("_seibetu_", status[1]))    #置き換えてくれる
    print("\e[m")
    gets
  end
end

def encounter(list)                              #何のモンスターが出現するか決めてくれるメソッド
  return list[rand(list.length)]
end

def enemyturn(probability,monster,enemy,ability,current) #敵のターンの一連の処理をまとめたメソッド
  if probability > 2
    enemymagic(probability,monster,enemy,ability,current)
  else
    if rand(((enemy[probability][4]*1.5).round) + 1) < rand(enemy[probability][5] + 1)       #左:物理攻撃 右:魔法攻撃
      enemymagic(probability,monster,enemy,ability,current)                         #魔法攻撃
    else
      enemyattack(probability,monster,enemy,ability,current)                          #物理攻撃
    end
  end
end

def process(damage) #ダメージの表示をする
  if damage < 1
    puts("攻撃失敗")
  else
    printf("%dダメージ\n",damage) #ダメージの表示
  end
end

def  battle(probability,monster,enemy,ability,current,item,status,nani,lv,g,attack,attackdetail,battleselect) #バトルの一連の処理をまとめた"すごい"メソッド
  escape = [1]
  printf("%s\e[mが現れた\n",monster)
  print("戦闘")
  dot(0.01,28,"=")
  print("\n")
  turn = rand(2)
  enemy[probability][0] = enemy[probability][1]
  enemy[probability][2] = enemy[probability][3]
  while true
    if current[0] <= 0
      return 0                  #負け
    elsif enemy[probability][0] <= 0
      return 1                  #勝ち
    elsif escape[0] == 0
      return 2
    end
    
    if ability[5] < enemy[probability][7] #敵の方がDEXが早かったとき
      enemyturn(probability,monster,enemy,ability,current)
      
      if current[0] <= 0
        return 0                  #負け
      elsif enemy[probability][0] <= 0
        return 1                  #勝ち
      elsif escape[0] == 0
        return 2
      end
      
      myturn(probability,monster,enemy,ability,current,item,status,nani,lv,g,attack,attackdetail,battleselect,escape)
      
    elsif ability[5] == enemy[probability][7] #敵とPLのDEXが同じ値だったとき
      
      if turn  == 0
        
        myturn(probability,monster,enemy,ability,current,item,status,nani,lv,g,attack,attackdetail,battleselect,escape)

        if current[0] <= 0
          return 0                  #負け
        elsif enemy[probability][0] <= 0
          return 1                  #勝ち
        elsif escape[0] == 0
          return 2
        end

        enemyturn(probability,monster,enemy,ability,current)
        
      else
        enemyturn(probability,monster,enemy,ability,current)

        if current[0] <= 0
          return 0                  #負け
        elsif enemy[probability][0] <= 0
          return 1                  #勝ち
        elsif escape[0] == 0
          return 2
        end
        
        myturn(probability,monster,enemy,ability,current,item,status,nani,lv,g,attack,attackdetail,battleselect,escape)
      end

    elsif ability[5] > enemy[probability][5] #PLの方がDEXが早かったとき
      myturn(probability,monster,enemy,ability,current,item,status,nani,lv,g,attack,attackdetail,battleselect,escape)

      if current[0] <= 0
        return 0                  #負け
      elsif enemy[probability][0] <= 0
        return 1                  #勝ち
      elsif escape[0] == 0
        return 2
      end
      
      enemyturn(probability,monster,enemy,ability,current)
    end
  end
end


def enemymagic(probability,monster,enemy,ability,current) #敵の魔法攻撃の処理
  if not enemy[probability][2] == 0
    print("\n")
    printf("%s\e[mの攻撃\n",monster)
    mp = (enemy[probability][3])/10.round + rand(3)+1
    if  mp > enemy[probability][2]
      mp = enemy[probability][2]
    elsif mp > 100
      mp = 100
    end
    damage = (enemy[probability][5] + (mp / 2).round - current[1] / 2).floor
    printf("%s!",enemy[probability][12])
    enemy[probability][2] -= mp
    damage += (damage/10).floor*rand(3) + rand(4)
    if damage <= 0
      if damage <= -100
        damage = 0
      else
      damage = rand(4)
      end
    end
    if  rand(enemy[probability][8]*2 + enemy[probability][7] + (enemy[probability][9]/2).floor*2) > rand(((ability[5]*2 + ability[6] + (ability[7]/2).floor)/2).floor)
      if rand(enemy[probability][8]*2 + enemy[probability][7] + (enemy[probability][9]/2).floor/4) > rand(((ability[5]*2 + ability[6] + (ability[7]/2).floor)/2).floor)
        damage = (damage*1.5).floor
      end
      current[0] -= damage
    else
      damage = 0
    end
  else
    damage = 0
  end
  process(damage)
end

def enemyattack(probability,monster,enemy,ability,current) #敵の物理攻撃の処理
  print("\n")
  printf("%s\e[mの攻撃\n",monster)
  damage = enemy[probability][4] - ability[4]/2.floor
  damage += (damage/10).floor*rand(3) + rand(4)
  printf("%s!",enemy[probability][11])
  if damage <= 0
    if damage <= -100
      damage = 0
    else
    damage = rand(4)
    end
  end
  if  rand(enemy[probability][8]*2 + enemy[probability][7] + (enemy[probability][9]/2).floor*2) > rand(((ability[5]*2 + ability[6] + (ability[7]/2).floor)/2).floor)
    if rand(enemy[probability][8]*2 + enemy[probability][7] + (enemy[probability][9]/2).floor/4) > rand(((ability[5]*2 + ability[6] + (ability[7]/2).floor)/2).floor)
      damage = (damage*1.5).floor
    end
    current[0] -= damage
  else
    damage = 0
  end
  process(damage)
end

def myturn(probability,monster,enemy,ability,current,item,status,nani,lv,g,attack,attackdetail,battleselect,escape)
  status(status,ability,current,nani,lv,g)
  select = question("行動…",battleselect)
  if select == "攻撃"
    select = query("攻撃…",attack)
    damage = ability[2] * attackdetail[select][0] - ((enemy[probability][6] / 2).floor)
    damage += (damage/10).floor*rand(3) + rand(4)
    if damage <= 0
      if damage <= -100
        damage = 0
      else
        damage = rand(4)
      end
    end
    if rand(enemy[probability][7]*2 + enemy[probability][8] + (enemy[probability][9]/2).floor) < rand((((ability[6]*2 + ability[5] + (ability[7]/2).floor)/2).floor)*2)
      if rand(enemy[probability][7]*2 + enemy[probability][8] + (enemy[probability][9]/2).floor) < rand(((ability[6]*2 + ability[5] + (ability[7]/2).floor)/2).floor/4)
        damage = (damage*1.5).floor
      end
    else
      damage = 0
    end
    current[1] -= attackdetail[select][1]
    current[0] -= attackdetail[select][2]
    printf("%s!",attack[select])
    
    enemy[probability][0] -= damage
    process(damage)
    damage = 0

  elsif select == "アイテム"


  elsif select == "逃げる"
    if rand((ability[5] + ability[7])*2) > rand(enemy[probability][7] + enemy [probability][9])
      puts("逃げ切れた")
      escape[0] = 0
      return
    else
      puts("逃げ切れなかった")
      return
    end
    
  end
end

#detaの配列は[0]がダメージ[1]が消費MP[2]が反動ダメージ

def game(probability,monster,enemy,ability,current,item,status,nani,lv,g,attack,attackdetail,battleselect,searchselect,lvup,count)
  sleep(rand(40)/10)
  result = battle(probability,monster[probability],enemy,ability,current,item,status,nani,lv,g,attack,attackdetail,battleselect)
  count[0] += 1
  if 0 == result
    gameovre                #GAMEOVREのメソッド
    current[0] = ability[0] #HP全快
    current[1] = ability[1] #MP全快
    g[0] -= ((g[0]/10).floor + 10)#Gを減らす
    if g[0] < 0                #Gが0未満になった場合
      g[0] = 0
    end
    count[2] += 1
    return 0
    
  elsif 1 == result
    print("\n")
    printf("%sに勝った!\n",monster[probability])
    x = enemy[probability][10] + ((enemy[probability][10]/10).floor * (rand(3) + 1) + (rand(3) + 1))
    lv[1] += x
    lv[2] += x
    g[0] += ((enemy[probability][10] + ((enemy[probability][10]/10).floor * (rand(3) + 1) + (rand(3) + 1)))*1.5).floor
    level(lv,lvup,status,ability,current,nani,g)
    count[1] += 1
    select = question("どうする",searchselect)
    if select == "拠点に戻る"
      return 0
    end
    
  elsif 2 == result
    count[3] += 1
    return 0
  end
  return 1
end

def appearance(monster,enemy,ability,current,item,status,nani,lv,g,attack,attackdetail,battleselect,kakuritu,n,limit,searchselect,lvup,count)
  while not n == limit
    probability = encounter(kakuritu[n])
    if 0 == game(probability,monster,enemy,ability,current,item,status,nani,lv,g,attack,attackdetail,battleselect,searchselect,lvup,count)
      return 0
    end
    n += 1
    if n == limit
      puts("この先から禍々しい気配がする それでも進みますか?")
      if "深部に進む" == question("どうする",searchselect)
      #ボス用メソッド
      else
        return 0
      end
    end
  end
end

def gameovre
  puts("GAMEOVER")
  picture = spawn "display -geometry +0+0 gameover.png"
  gets
  Process.kill(:INT,picture)
end



def level(lv,lvup,status,ability,current,nani,g)
  exp = lvup[1]
  if not lv[0] == "50(MAX)" ||  lv[0] == "\e[93mSPECIAL\e[m"
    while 0 >= exp-lv[2]
      puts("レベルアップ!")
      x = lv[0]+1
      printf("Lv%s→Lv%s\n",lv[0],x)
      lv[0] += 1
      lvup[0] = lvup[1]
      lvup[1] = (lvup[0]*1.2).floor
      ability[0] = (ability[0]*1.065).ceil
      ability[1] = (ability[1]*1.1).ceil
      ability[2] = (ability[2]*1.04).ceil
      ability[3] = (ability[3]*1.035).ceil
      ability[4] = (ability[4]*1.05).ceil
      ability[5] = (ability[5]*1.045).ceil
      ability[6] = (ability[6]*1.045).ceil
      ability[7] = lv[0]
      lv[2] -= exp
      if lv[0] == 50
        lv[0] = "50(MAX)"
        ability[1] = 800
        ability[2] = 120
        ability[4] = 150
        ability[5] = 250
        ability[6] = 200
      end
    end
  end
  status(status,ability,current,nani,lv,g)
end

while true
  puts("RPG")                     #ここから やっとメソッドじゃない
  select = question("選択",sentaku)
  if select == "ゲーム説明"
    print("\n")
    description(gamedescription)
    redo
  end
  if select == "クレジットタイトル"
    print("\n")
    description(credit)
    redo
  end

  if select == "プレイ"
    name = ""
    puts("PL名を決めてください")
    while name == ""             #この辺少し変だから真似はよく見てやって
      print("name…")
      name = gets.chomp
      if name == "administrator" || name == "管理者" #スーパーアカウント(^_^;)
        lv[0] = "\e[93mSPECIAL\e[m"
        ability[0] = 1000
        ability[1] = 1500
        ability[2] = 500
        ability[3] = 300
        ability[4] = 400
        ability[5] = 500
        ability[6] = 400
        ability[7] = 100
        current[0] =  ability[0]
        current[1] =  ability[1]
        g[0] = 100000000
        puts("スーパーアカウントの使用を許可します")
        puts("PL名を決めてください")
        redo
      end
    end
    name = name.chomp
    status << name
    status << question("性別を決めてください",q1)
    status << question("一人称を決めてください",q2)
  end

  puts("ゲームを起動します")
  sleep(1)

  print"Loading"
  dot(0.5,3,".")                     #「.」を0.5秒間隔で3回表示する
  sleep(1)
  print("\n\n")

  story(prorogu,status)           #ストーリを表示する

  progress += 1                   #進行度を進める

  area << "ポルタ平原"            #行けるエリアを増やす

  while true       #今のところ見るだけ。選択肢の中身ができたらいじる
    puts("               メニュー")
    x = 0
    y = question("行動…",nani[4])      #yはPLの回答を拾ってくる 
    print("\n")

    if y == "ステータスを見る"
      status(status,ability,current,nani,lv,g)
      
    elsif y == "宿屋に行く"
      puts("宿屋の主人:一泊10Gだよ")
      select = question("どうする",yadoya)
      if select == "泊まる10G"
        if g[0] >= 10                #10Gで泊まれる
          g[0] -= 10
          print"Sleeing"
          dot(0.5,3,".")
          sleep(1)
          print("\n")
          current[0] =  ability[0]
          current[1] =  ability[1]
          puts("宿屋の主人:また 来いよ")     #泊まるとHPとMPが全快する
          
        else
          puts("宿屋の主人:お前 金持ってないのか!")
          puts("宿屋の主人:ひやかしは帰れ!!") #お金が足りなかった場合
        end
      else
        puts("宿屋の主人:なんだ泊まんねーのかよ") #泊まんなかった場合
      end
      print("\n")
      
    elsif y == "探索に行く"
      select = question("どこに探索に行きますか",area) #どこに行くかの選択
      if select == "ポルタ平原"
        n = 0
        limit = 5
        appearance(monster,enemy,ability,current,item,status,nani,lv,g,attack,attackdetail,battleselect,kakuritu,n,limit,searchselect,lvup,count)
        redo
        
      end
    end
  end
  
  redo
end