バッティングルーレットを作ります。
数字が0から9に回るのなら簡単ですが、
野球ゲーム用のルーレットなので、
単純にアウト、ヒット、ホームランの出目を循環させるわけにはいきません。
なぜなら、ヒットの確率が高くなり、ゲーム性が失われてしまいます。
そこで、下図*1のようなルーレットをつくります。
このようにすれば、ヒットの確率を調整することができます。
では、これをどのようにプログラムするのかというと、
クロックのタイミング*2で、アウト→フォアボール→アウト→アウト→アウト...
と状態を変化させ、ストップがかかったタイミングで出目を確定させればよいのです。
この状態を変化させるには、ステートマシンを使用します。
今回、ノーマルモード*3とチャレンジモード*4用にステートマシンを2つ作って、ヒットの確率を変えてみます。
また、目押し用*5にホームランのタイミングで信号(ASSIST<= '1')が出るようにします。
-- Batting Roullet
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity BATTING_ROULLET is
port(
CLK : in std_logic;
RESET : in std_logic;
STARTSTOP : in std_logic;
MODE : in std_logic;
BATTING : out std_logic_vector(2 downto 0);
ASSIST : out std_logic
);
end BATTING_ROULLET;
architecture RTL of BATTING_ROULLET is
type STATE_TYPE is (
ONEBASE0,ONEBASE1,ONEBASE2,ONEBASE3,ONEBASE4,
TWOBASE0,TWOBASE1,
THREEBASE0,THREEBASE1,
HOMERUN0,HOMERUN1,HOMERUN2,
FOUR0,FOUR1,FOUR2,FOUR3,FOUR4,
OUT0,OUT1,OUT2,OUT3,OUT4,OUT5,OUT6,OUT7,OUT8,OUT9,
OUT10,OUT11,OUT12,OUT13,OUT14,OUT15,OUT16,OUT17,OUT18,OUT19,
OUT20,OUT21,OUT22,OUT23,
CHANGE
);
signal STATE : STATE_TYPE;
begin
process(CLK,RESET)
begin
if (RESET = '0') then
STATE <= CHANGE;
elsif(CLK'event and CLK = '0') then
if (STARTSTOP = '1') then
if (MODE = '0') then
case(STATE) is -- Normal MODE
when CHANGE => STATE <= OUT0;
when OUT0 => STATE <= FOUR0;
when FOUR0 => STATE <= OUT1;
when OUT1 => STATE <= TWOBASE0;
when TWOBASE0 => STATE <= OUT2;
when OUT2 => STATE <= OUT3;
when OUT3 => STATE <= OUT4;
when OUT4 => STATE <= THREEBASE0;
when THREEBASE0 => STATE <= OUT5;
when OUT5 => STATE <= ONEBASE0;
when ONEBASE0 => STATE <= OUT6;
when OUT6 => STATE <= FOUR1;
when FOUR1 => STATE <= OUT7;
when OUT7 => STATE <= ONEBASE1;
when ONEBASE1 => STATE <= OUT8;
when OUT8 => STATE <= FOUR2;
when FOUR2 => STATE <= OUT9;
when OUT9 => STATE <= ONEBASE2;
when ONEBASE2 => STATE <= OUT10;
when OUT10 => STATE <= TWOBASE1;
when TWOBASE1 => STATE <= OUT11;
when OUT11 => STATE <= OUT12;
when OUT12 => STATE <= OUT13;
when OUT13 => STATE <= HOMERUN0;
when HOMERUN0 => STATE <= OUT14;
when OUT14 => STATE <= FOUR3;
when FOUR3 => STATE <= OUT15;
when OUT15 => STATE <= ONEBASE3;
when ONEBASE3 => STATE <= OUT16;
when OUT16 => STATE <= FOUR4;
when FOUR4 => STATE <= OUT17;
when OUT17 => STATE <= ONEBASE4;
when ONEBASE4 => STATE <= OUT0;
when others => STATE <= CHANGE;
end case;
else
case(STATE) is -- Challenge MODE
when CHANGE => STATE <= OUT0;
when OUT0 => STATE <= OUT1;
when OUT1 => STATE <= OUT2;
when OUT2 => STATE <= HOMERUN0;
when HOMERUN0 => STATE <= OUT3;
when OUT3 => STATE <= OUT4;
when OUT4 => STATE <= ONEBASE0;
when ONEBASE0 => STATE <= OUT5;
when OUT5 => STATE <= OUT6;
when OUT6 => STATE <= TWOBASE0;
when TWOBASE0 => STATE <= OUT7;
when OUT7 => STATE <= OUT8;
when OUT8 => STATE <= OUT9;
when OUT9 => STATE <= THREEBASE0;
when THREEBASE0 => STATE <= OUT10;
when OUT10 => STATE <= OUT11;
when OUT11 => STATE <= OUT12;
when OUT12 => STATE <= OUT13;
when OUT13 => STATE <= OUT14;
when OUT14 => STATE <= HOMERUN1;
when HOMERUN1 => STATE <= OUT15;
when OUT15 => STATE <= OUT16;
when OUT16 => STATE <= FOUR0;
when FOUR0 => STATE <= OUT17;
when OUT17 => STATE <= OUT18;
when OUT18 => STATE <= HOMERUN2;
when HOMERUN2 => STATE <= OUT19;
when OUT19 => STATE <= OUT20;
when OUT20 => STATE <= OUT21; when OUT21 => STATE <= THREEBASE1;
when THREEBASE1 => STATE <= OUT22; when OUT22 => STATE <= OUT23; when OUT23 => STATE <= OUT0;
when others => STATE <= CHANGE;
end case;
end if;
end if;
end if;
end process;
process(STATE)
begin
case(STATE) is
when CHANGE =>
BATTING <= "110";
ASSIST <= '0';
when OUT0 =>
BATTING <= "000";
ASSIST <= '0';
when OUT1 =>
BATTING <= "000";
ASSIST <= '0';
when OUT2 =>
BATTING <= "000";
ASSIST <= '0';
when OUT3 =>
BATTING <= "000";
ASSIST <= '0';
when OUT4 =>
BATTING <= "000";
ASSIST <= '0';
when OUT5 =>
BATTING <= "000";
ASSIST <= '0';
when OUT6 =>
BATTING <= "000";
ASSIST <= '0';
when OUT7 =>
BATTING <= "000";
ASSIST <= '0';
when OUT8 =>
BATTING <= "000";
ASSIST <= '0';
when OUT9 =>
BATTING <= "000";
ASSIST <= '0';
when OUT10 =>
BATTING <= "000";
ASSIST <= '0';
when OUT11 =>
BATTING <= "000";
ASSIST <= '0';
when OUT12 =>
BATTING <= "000";
ASSIST <= '0';
when OUT13 =>
BATTING <= "000";
ASSIST <= '0';
when OUT14 =>
BATTING <= "000";
ASSIST <= '0';
when OUT15 =>
BATTING <= "000";
ASSIST <= '0';
when OUT16 =>
BATTING <= "000";
ASSIST <= '0';
when OUT17 =>
BATTING <= "000";
ASSIST <= '0';
when OUT18 =>
BATTING <= "000";
ASSIST <= '0';
when OUT19 =>
BATTING <= "000";
ASSIST <= '0';
when OUT20 =>
BATTING <= "000";
ASSIST <= '0';
when OUT21 =>
BATTING <= "000";
ASSIST <= '0';
when OUT22 =>
BATTING <= "000";
ASSIST <= '0';
when OUT23 =>
BATTING <= "000";
ASSIST <= '0';
when ONEBASE0 =>
BATTING <= "001";
ASSIST <= '0';
when ONEBASE1 =>
BATTING <= "001";
ASSIST <= '0';
when ONEBASE2 =>
BATTING <= "001";
ASSIST <= '0';
when ONEBASE3 =>
BATTING <= "001";
ASSIST <= '0';
when ONEBASE4 =>
BATTING <= "001";
ASSIST <= '0';
when TWOBASE0 =>
BATTING <= "010";
ASSIST <= '0';
when TWOBASE1 =>
BATTING <= "010";
ASSIST <= '0';
when THREEBASE0 =>
BATTING <= "011";
ASSIST <= '0';
when THREEBASE1 =>
BATTING <= "011";
ASSIST <= '0';
when HOMERUN0 =>
BATTING <= "100";
ASSIST <= '1';
when HOMERUN1 =>
BATTING <= "100";
ASSIST <= '1';
when HOMERUN2 =>
BATTING <= "100";
ASSIST <= '1';
when FOUR0 =>
BATTING <= "101";
ASSIST <= '0';
when FOUR1 =>
BATTING <= "101";
ASSIST <= '0';
when FOUR2 =>
BATTING <= "101";
ASSIST <= '0';
when FOUR3 =>
BATTING <= "101";
ASSIST <= '0';
when FOUR4 =>
BATTING <= "101";
ASSIST <= '0';
when others =>
BATTING <= "000";
ASSIST <= '0';
end case;
end process;
end RTL;
*1:何で作図したらよいかわからなかったので、大げさにもCADで作図しました。
*2:ということは、クロックの速度を変えれば、ルーレットが回る速度が変わります。
*3:ヒットの確率は高いが、シングルヒットが多い
*4:ヒットの確率は低いが、出れば長打になる
*5:ズル用とも