Yu-Gi-Oh! Forbidden Memories - Battle Rank
Mix . install ( [
{ :kino , "~> 0.12.3" }
] )
import Kino
import Kino.Shorts
nothing ( )
defmodule FieldScore do
def calc ( field , x ) when is_nil ( x ) , do: calc ( field , 0 )
def calc ( :number_of_turns , x ) when x >= 0 and x <= 4 , do: + 12
def calc ( :number_of_turns , x ) when x >= 5 and x <= 8 , do: + 8
def calc ( :number_of_turns , x ) when x >= 9 and x <= 28 , do: + 0
def calc ( :number_of_turns , x ) when x >= 29 and x <= 32 , do: - 8
def calc ( :number_of_turns , x ) when x >= 33 , do: - 12
def calc ( :effective_attacks , x ) when x >= 0 and x <= 1 , do: + 4
def calc ( :effective_attacks , x ) when x >= 2 and x <= 3 , do: + 2
def calc ( :effective_attacks , x ) when x >= 4 and x <= 9 , do: + 0
def calc ( :effective_attacks , x ) when x >= 10 and x <= 19 , do: - 2
def calc ( :effective_attacks , x ) when x >= 20 , do: - 4
def calc ( :defensive_wins , x ) when x >= 0 and x <= 1 , do: + 0
def calc ( :defensive_wins , x ) when x >= 2 and x <= 5 , do: - 10
def calc ( :defensive_wins , x ) when x >= 6 and x <= 9 , do: - 20
def calc ( :defensive_wins , x ) when x >= 10 and x <= 14 , do: - 30
def calc ( :defensive_wins , x ) when x >= 15 , do: - 40
def calc ( :face_down_plays , x ) when x == 0 , do: + 0
def calc ( :face_down_plays , x ) when x >= 1 and x <= 10 , do: - 2
def calc ( :face_down_plays , x ) when x >= 11 and x <= 20 , do: - 4
def calc ( :face_down_plays , x ) when x >= 21 and x <= 30 , do: - 6
def calc ( :face_down_plays , x ) when x >= 31 , do: - 8
def calc ( :initiate_fusion , x ) when x == 0 , do: + 4
def calc ( :initiate_fusion , x ) when x >= 1 and x <= 4 , do: + 0
def calc ( :initiate_fusion , x ) when x >= 5 and x <= 9 , do: - 4
def calc ( :initiate_fusion , x ) when x >= 10 and x <= 14 , do: - 8
def calc ( :initiate_fusion , x ) when x >= 15 , do: - 12
def calc ( :equip_magic , x ) when x == 0 , do: + 4
def calc ( :equip_magic , x ) when x >= 1 and x <= 4 , do: + 0
def calc ( :equip_magic , x ) when x >= 5 and x <= 9 , do: - 4
def calc ( :equip_magic , x ) when x >= 10 and x <= 14 , do: - 8
def calc ( :equip_magic , x ) when x >= 15 , do: - 12
def calc ( :pure_magic , x ) when x == 0 , do: + 2
def calc ( :pure_magic , x ) when x >= 1 and x <= 3 , do: - 4
def calc ( :pure_magic , x ) when x >= 4 and x <= 6 , do: - 8
def calc ( :pure_magic , x ) when x >= 7 and x <= 9 , do: - 12
def calc ( :pure_magic , x ) when x >= 10 , do: - 16
def calc ( :trigger_trap , x ) when x == 0 , do: + 2
def calc ( :trigger_trap , x ) when x >= 1 and x <= 2 , do: - 8
def calc ( :trigger_trap , x ) when x >= 3 and x <= 4 , do: - 16
def calc ( :trigger_trap , x ) when x >= 5 and x <= 6 , do: - 24
def calc ( :trigger_trap , x ) when x >= 7 , do: - 32
def calc ( :cards_used , x ) when x >= 0 and x <= 8 , do: + 15
def calc ( :cards_used , x ) when x >= 9 and x <= 12 , do: + 12
def calc ( :cards_used , x ) when x >= 13 and x <= 32 , do: + 0
def calc ( :cards_used , x ) when x >= 33 and x <= 36 , do: - 5
def calc ( :cards_used , x ) when x >= 37 , do: - 7
def calc ( :remaining_lp , x ) when x >= 0 and x <= 99 , do: - 7
def calc ( :remaining_lp , x ) when x >= 100 and x <= 999 , do: - 5
def calc ( :remaining_lp , x ) when x >= 1000 and x <= 6999 , do: + 0
def calc ( :remaining_lp , x ) when x >= 7000 and x <= 7999 , do: + 4
def calc ( :remaining_lp , x ) when x >= 8000 , do: + 6
end
nothing ( )
fields = [
# {:victory_condition, "Victory condition", 0},
{ :number_of_turns , "Number of turns" , 0 } ,
{ :effective_attacks , "Effective attacks" , 0 } ,
{ :defensive_wins , "Defensive wins" , 0 } ,
{ :face_down_plays , "Face-down plays" , 0 } ,
{ :initiate_fusion , "Initiate Fusion" , 0 } ,
{ :equip_magic , "Equip Magic" , 0 } ,
{ :pure_magic , "Pure Magic" , 0 } ,
{ :trigger_trap , "Trigger Trap" , 0 } ,
{ :cards_used , "Cards used" , 0 } ,
{ :remaining_lp , "Remaining LP" , 8000 }
]
settings = [ debounce: 200 ]
inputs =
Enum . map ( fields , fn { field , label , default } ->
{ field , Kino.Input . number ( label , [ { :default , default } | settings ] ) }
end )
# submit = Kino.Control.button("Calculate")
input_frame = Kino.Frame . new ( )
Kino.Frame . render (
input_frame ,
Kino.Layout . grid (
[
Kino.Layout . grid ( Keyword . values ( inputs ) , columns: 3 )
# submit
] ,
gap: 16 ,
boxed: true
)
)
input_frame
import FieldScore
frame = Kino.Frame . new ( )
render = fn state ->
get_field_value = fn field , default ->
Map . get ( state , field , default )
end
score =
Enum . reduce ( fields , 52 , fn { field , _ , default } , acc ->
acc + calc ( field , get_field_value . ( field , default ) )
end )
rank =
case score do
x when x <= 9 -> { :technical , "S" }
x when x >= 10 and x <= 19 -> { :technical , "A" }
x when x >= 20 and x <= 29 -> { :technical , "B" }
x when x >= 30 and x <= 39 -> { :technical , "C" }
x when x >= 40 and x <= 49 -> { :technical , "D" }
x when x >= 50 and x <= 59 -> { :power , "D" }
x when x >= 60 and x <= 69 -> { :power , "C" }
x when x >= 70 and x <= 79 -> { :power , "B" }
x when x >= 80 and x <= 89 -> { :power , "A" }
x when x >= 90 -> { :power , "S" }
end
rank_cat =
rank
|> elem ( 0 )
|> Atom . to_string ( )
|> String . slice ( 0 .. 2 )
|> String . upcase ( )
content =
"""
# Rank #{ rank_cat } -#{ elem ( rank , 1 ) }
Score: **#{ score } **
| Param | Value | Score |
| ----- | ------ | ----- |
""" <>
( fields
|> Enum . map ( fn { field , label , default } ->
value = get_field_value . ( field , default )
"| #{ label } |#{ value } | #{ calc ( field , value ) } |"
end )
|> Enum . join ( "\n " ) )
Kino.Frame . render ( frame , Kino.Markdown . new ( content ) )
end
initial =
fields
|> Enum . map ( fn { field , _ , _ } -> { field , Kino.Input . read ( inputs [ field ] ) } end )
|> Enum . into ( % { } )
render . ( initial )
inputs
# |> Keyword.put(:submit, submit)
|> Kino.Control . tagged_stream ( )
|> Kino . listen ( initial , fn event , state ->
case event do
# {:submit, _} ->
# {:cont, state}
{ field , % { value: value } } ->
state = Map . put ( state , field , value )
render . ( state )
{ :cont , state }
end
end )
frame