LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;

Entity Snake is
	PORT(CLK:IN STD_LOGIC;
		 SWUP:IN STD_LOGIC;
		 SWDN:IN STD_LOGIC;
		 SWRT:IN STD_LOGIC;
		 SWLF:IN STD_LOGIC;
		 H_Scan:Buffer STD_LOGIC_VECTOR(15 downto 0);
		 V_Scan:OUT STD_LOGIC_VECTOR(15 downto 0));
End Snake;

Architecture a of Snake is
	Type Arr is array(0 to 31)of STD_LOGIC_VECTOR(3 downto 0);
	Signal Vertical: STD_LOGIC_VECTOR(3 downto 0);
	Signal Dly: STD_LOGIC_VECTOR(19 downto 0);
	Signal Rdm: STD_LOGIC_VECTOR(7 downto 0);
	Signal FdNd: STD_LOGIC:='0';
	Signal GmEnd: STD_LOGIC:='0';
   Signal Score: integer:=0;
	Signal Len: integer:=8;
	Signal P_x: Arr;
	Signal P_y: Arr;
	Signal F_x: STD_LOGIC_VECTOR(3 downto 0);
	Signal F_y: STD_LOGIC_VECTOR(3 downto 0);
	Signal Dir: STD_LOGIC_VECTOR(1 downto 0):="11";
	Signal CLKS: STD_LOGIC;
BEGIN

Process(CLK)
Variable k: integer := 0;
	Begin
		if(CLK'Event and CLK='1')then
			if(Rdm="00000000")then
				Rdm<="00000001";
			else
				Rdm(0)<=Rdm(0) Xor Rdm(1) Xor Rdm(2) Xor Rdm(7);
				Rdm(1)<=Rdm(0);
				Rdm(2)<=Rdm(1);
				Rdm(3)<=Rdm(2);
				Rdm(4)<=Rdm(3);
				Rdm(5)<=Rdm(4);
				Rdm(6)<=Rdm(5);
				Rdm(7)<=Rdm(6);
			End if;
			if(SWUP='0')then
				Dir<="00";
			Elsif(SWDN='0')then
				Dir<="01";
			Elsif(SWLF='0')then
			   Dir<="10";
			Elsif(SWRT='0')then
				Dir<="11";
			End if;
			for k in 0 to Len-1 loop
				if(k<=Score and Score>1)then
					if(P_x(0)=P_x(k+1))then
						if(P_y(0)=P_y(k+1))then
							GmEnd<='1';
						End if;
					End if;
				End if;
			End loop;
		End if;
End Process;

Process(FdNd)
Variable l: integer :=0;
Variable Tr: STD_LOGIC :='1';
	Begin
		if(FdNd='1')then
			for l in 0 to Len loop
				if(l<=Score)then
					if(Rdm(7 downto 4)=P_x(l) and Rdm(3 downto 0)=P_y(l))then
						Tr:='0';
					End if;
				End if;
			End loop;
			if(Tr='1')then
				F_x<=Rdm(7 downto 4);
				F_y<=Rdm(3 downto 0);
			End if;
		End if;
End Process;
	
Process(CLK)
	Begin
		if(CLK'Event and CLK='1')then
			if(GmEnd='0')then
				Dly<=Dly+1;
				if(Dly="11111111111111111111")then
					CLKS<='0';
				Elsif(Dly="01111111111111111111")then
					CLKS<='1';
				End if;
			End if;
		End if;
End Process;

Process(CLKS)
Variable j: integer := 0;
	Begin
		if(CLKS'Event and CLKS='0')then
			for j in 0 to Len loop
				if(j<=Score)then
					P_x(j+1)<=P_x(j);
					P_y(j+1)<=P_y(j);
				End if;
			End loop;
			if(Dir="00")then
				P_y(0)<=P_y(0)+1;
			Elsif(Dir="01")then
				P_y(0)<=P_y(0)-1;
			Elsif(Dir="10")then
				P_x(0)<=P_x(0)-1;
			Elsif(Dir="11")then
				P_x(0)<=P_x(0)+1;
			End if;
		End if;
End Process;

Process(CLKS)
	Begin
		if(CLKS'Event and CLKS='1')then
			if(F_x=P_x(0) and F_y=P_y(0))then
				FdNd<='1';
				Score<=Score+1;
			Else
				FdNd<='0';
			End if;
		End if;
End Process;
		
Process(CLK)
	Begin
		if(CLK'Event and CLK='1')then
			Vertical<=Vertical+1;
		End if;
End Process;

Process(CLK)
Variable i: integer := 0;
	Begin
		if(CLK'Event and CLK='1')then
				H_Scan<="1111111111111111";
			for i in 0 to Len loop
				if(i<=Score)then
					if(P_y(i)=Vertical)then
						if(P_x(i)="0000")then
							H_Scan(15)<='0';
						Elsif(P_x(i)="0001")then
							H_Scan(14)<='0';
						Elsif(P_x(i)="0010")then
							H_Scan(13)<='0';
						Elsif(P_x(i)="0011")then
							H_Scan(12)<='0';
						Elsif(P_x(i)="0100")then
							H_Scan(11)<='0';
						Elsif(P_x(i)="0101")then
							H_Scan(10)<='0';
						Elsif(P_x(i)="0110")then
							H_Scan(9)<='0';
						Elsif(P_x(i)="0111")then
							H_Scan(8)<='0';
						Elsif(P_x(i)="1000")then
							H_Scan(7)<='0';
						Elsif(P_x(i)="1001")then
							H_Scan(6)<='0';
						Elsif(P_x(i)="1010")then
							H_Scan(5)<='0';
						Elsif(P_x(i)="1011")then
							H_Scan(4)<='0';
						Elsif(P_x(i)="1100")then
							H_Scan(3)<='0';
						Elsif(P_x(i)="1101")then
							H_Scan(2)<='0';
						Elsif(P_x(i)="1110")then
							H_Scan(1)<='0';
						Elsif(P_x(i)="1111")then
							H_Scan(0)<='0';
						End if;
					End if;
				End if;
			End loop;
				if(F_y=Vertical)then
					if(F_x="0000")then
						H_Scan(15)<='0';
					Elsif(F_x="0001")then
						H_Scan(14)<='0';
					Elsif(F_x="0010")then
						H_Scan(13)<='0';
					Elsif(F_x="0011")then
						H_Scan(12)<='0';
					Elsif(F_x="0100")then
						H_Scan(11)<='0';
					Elsif(F_x="0101")then
						H_Scan(10)<='0';
					Elsif(F_x="0110")then
						H_Scan(9)<='0';
					Elsif(F_x="0111")then
						H_Scan(8)<='0';
					Elsif(F_x="1000")then
						H_Scan(7)<='0';
					Elsif(F_x="1001")then
						H_Scan(6)<='0';
					Elsif(F_x="1010")then
						H_Scan(5)<='0';
					Elsif(F_x="1011")then
						H_Scan(4)<='0';
					Elsif(F_x="1100")then
						H_Scan(3)<='0';
					Elsif(F_x="1101")then
						H_Scan(2)<='0';
					Elsif(F_x="1110")then
						H_Scan(1)<='0';
					Elsif(F_x="1111")then
						H_Scan(0)<='0';
					End if;
				End if;
		End if;
End Process;

	WITH Vertical SELECT
 V_Scan<="1000000000000000"WHEN"0000",
			"0100000000000000"WHEN"0001",
			"0010000000000000"WHEN"0010",
			"0001000000000000"WHEN"0011",
			"0000100000000000"WHEN"0100",
			"0000010000000000"WHEN"0101",
			"0000001000000000"WHEN"0110",
			"0000000100000000"WHEN"0111",
			"0000000010000000"WHEN"1000",
			"0000000001000000"WHEN"1001",
			"0000000000100000"WHEN"1010",
			"0000000000010000"WHEN"1011",
			"0000000000001000"WHEN"1100",
			"0000000000000100"WHEN"1101",
			"0000000000000010"WHEN"1110",
			"0000000000000001"WHEN"1111";
END a;