houseplayer.vhd


LIBRARY ieee ;
USE ieee.std_logic_1164.all ;
USE  IEEE.STD_LOGIC_ARITH.all;
USE  IEEE.STD_LOGIC_UNSIGNED.all;

ENTITY House_Player IS
	PORT (  clk				: IN	STD_LOGIC;
		reset				: IN	STD_LOGIC;
		Accept				: IN	STD_LOGIC; -- whether card on bus is yours to be read
		IN_Card				: IN 	STD_LOGIC_VECTOR(3 DOWNTO 0); -- input card from bus
		Most_Recent1, Most_Recent2 	: IN	STD_LOGIC_VECTOR(3 DOWNTO 0); -- 10 most recent cards
		Most_Recent3, Most_Recent4	: IN	STD_LOGIC_VECTOR(3 DOWNTO 0);
		Most_Recent5, Most_Recent6	: IN	STD_LOGIC_VECTOR(3 DOWNTO 0);
		Most_Recent7, Most_Recent8	: IN	STD_LOGIC_VECTOR(3 DOWNTO 0);
		Most_Recent9, Most_Recent10	: IN	STD_LOGIC_VECTOR(3 DOWNTO 0);
		NumA, Num2, Num3, Num4, Num5	: IN	STD_LOGIC_VECTOR(3 DOWNTO 0);-- total number of each card
		Num6, Num7, Num8, Num9, Num10	: IN	STD_LOGIC_VECTOR(3 DOWNTO 0);
		NumJ, NumQ, NumK		: IN	STD_LOGIC_VECTOR(3 DOWNTO 0);
		Dealer_Shows			: IN	STD_LOGIC_VECTOR(3 DOWNTO 0);--card dealer is showing
		Hit				: OUT	STD_LOGIC;  -- whether you should hit or not
		Stay				: OUT	STD_LOGIC ) ; -- whether you should stay or not
END House_Player ;

ARCHITECTURE Behavior OF House_Player IS	
BEGIN
PROCESS ( clk )
variable total 		: STD_LOGIC_VECTOR(4 DOWNTO 0); -- total value of cards
variable state		: STD_LOGIC_VECTOR(3 DOWNTO 0); -- current state variable
variable ace		: STD_LOGIC; -- whether or not you've used an ace as an 11
BEGIN
	IF(clk = '1' AND clk'EVENT) THEN
		IF(reset = '1') THEN -- reset
			total := "00000";
			state := "0000";
			hit <= '0';
			stay <= '1';
			ace := '0';
		ELSE
		CASE state IS
			WHEN "0000" => -- initial reset state
				hit <= '0'; 
				stay <= '1'; -- also state when you've determined you don't need anymore cards, so stay.
				ace := '0'; 
				total := "00000";
				IF(Accept = '1') THEN -- poll accept flag for first card
					IF(IN_Card > "1001") THEN -- if greater then 10, just add 10
						total := total + "1010";
					ELSIF(IN_Card = "0001") THEN -- if ace, add 11 and set ace flag
						total := total + "1011";
						ace := '1';
					ELSE
						total := total + IN_Card; -- otherwise add card value
					END IF;
					state := "0001"; -- move to next card state
				ELSE
					state := "0000"; -- continue polling accept flag
				END IF;
			WHEN "0001" => -- state in which you're getting any card after the first card
				hit <= '1'; -- you're always waiting to be hit, so tell control that
				stay <= '0'; -- not staying
				IF(Accept = '1') THEN -- if the card on the bus is yours, read it
					IF(IN_Card > "1001") THEN -- if it's greater then 10, just add 10
						total := total + "1010";
					ELSIF(IN_Card = "0001" AND ace = '0') THEN -- if it's an ace add 11
						total := total + "1011"; 
						ace := '1'
					ELSIF(IN_Card = "0001" AND ace = '1') THEN -- if you've already had an ace, add 1
						total := total + "0001";
					ELSE
						total := total + IN_Card; -- if it's a normal card, add the value
					END IF;

					state := "0010"; -- go onto hit/stay check
				ELSE
					state := "0001"; -- continue polling accept flag
				END IF;						
			WHEN "0010" => -- check hit/stay state
				IF(total < "10001") THEN -- if less then 17, you hit
					hit <= '1';
					stay <= '0';
					state := "0001";
				ELSIF(total < "10110") THEN -- if greater then 16, less then 22, you stay
					hit < '0';
					stay <= '1';
					state := "0000";
				ELSIF(total < "11011" AND ace = '1') THEN -- if you've busted with an ace, and it's below 27, hit
					total := total - "1010"; -- readjust total and reset ace flag
					ace := '0';
					hit <= '1';
					stay <= '0';
					state := "0001";
				ELSE -- at this point you either busted with or w/o an ace, either way you stay
					hit <= '0';
					stay <= '1';
					state := "0000";
				END IF;
			WHEN OTHERS =>
				null;
		END CASE;
		end if;
	end if;
	END PROCESS ;
END Behavior ;