#include #include #include #include /* Copyright (c) 2000 Jean-Marc Zucconi * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer * in this position and unchanged. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* original (PASCAL VAX) version : * * XXXX XXXXX X X * X X X X X * X X X XX * X X X X XX * X X X X X * XXX X XXXXX X X * * * * Program: Qix * * Author: Murray Speight * * Place: University Of Waikato * * Date : Mar 1982 * * Software Is Subject To Change Without Notification * The Author And His Family assume No Rsponsability For * Its Reliabliity Or Use. * * * A Game Derived From a Video Game Of The Same Name * */ #include "qix.h" #define MAX_LEN_SNAKE 40 typedef enum { Inside, Outside, Created, Other, Snake, Tmp, TmpN, TmpN2, TmpCreat } Wall_Types; struct Char_On_Screen { unsigned char Sym; Wall_Types Wall; } **Screen; typedef enum { Clockwise, AntiClockwise } Direction; int Marked_Clock_Greeb_X, Marked_Clock_Greeb_Y, Marked_Anti_Greeb_X, Marked_Anti_Greeb_Y, Num_Marked_Clock_Greeb, Num_Marked_Anti_Greeb, Last_Clock_Greeb_X, Last_Clock_Greeb_y, Last_Anti_Greeb_X, Last_Anti_Greeb_y, Clock_Greeb_X, Clock_Greeb_y, Anti_Greeb_X, Anti_Greeb_y, Extra_Greeb_X, Extra_Greeb_Y, Last_Extra_Greeb_X, Last_Extra_Greeb_Y, You_X, You_Y, Last_You_X, Last_You_Y, Move_X, Level, Move_y, Start_Creat_X, Start_Creat_Y, Last_Start_Creat_X, Last_Start_Creat_Y, Snake_After_X, Snake_After_Y, Snake_Head_X, Snake_Head_Y, Snake_Move_X, Snake_Move_Y, Snake_Tail_X, Lives, Score, Amt_Filled_In, Len_Snake, Len_Snake_When_Stuck, Num_Snake_Searched, Num_Moves_After_This_Pt, Moves_since_stuck, Snake_Tail_Y; int Can_Create_wall, Moving_Extra_Greebly, Marked_Clock_Greeb, Marked_Anti_Greeb, Snake_got_stuck, Died, Creating_wall; Direction Dir_You; /* Direction You Are moving In */ Direction Dir_When_Start_Creat; /* Direction You Were In Before Starting To Create */ void Sleep (int, int); void Help_Screen (); void Sleep_Set (int); void Sleep_Start (); void Sleep_Wait (); int leave (); void Pos (int, int, char); void Draw_Screen () { int X, Y; VT_clear (); for (Y = 1; Y <= HEIGHT-2; Y++) Pos (1, Y, Screen[1][Y].Sym); for (X = 2; X <=WIDTH-3; X++) { Pos (X, 1, Screen[X][1].Sym); Pos (X, HEIGHT-2, Screen[X][HEIGHT-2].Sym); } for (Y = 1; Y <= HEIGHT-2; Y++){ Sleep (0, 1); Pos (WIDTH-2, Y, Screen[WIDTH-2][Y].Sym); } VT_print_covered (); VT_covered (Amt_Filled_In * 100.0 / ((WIDTH-4)*(HEIGHT-4))); VT_print_score (); VT_score (Score); VT_print_lives (); VT_lives (Lives); VT_print_level (); VT_level (Level); Pos (Snake_Head_X, Snake_Head_Y, Qix_Head); Pos (You_X, You_Y, You); } int Rand (int X) { return drand48()*X+1; } char Correct_Sym (int X, int Y, int Compare_X, int Compare_Y) { char Result = 0; int Count = 0; if (Screen[X-1][Y].Sym == F_1F || Screen[X-1][Y].Sym == F_1C || Screen[X-1][Y].Sym == F_15 || Screen[X-1][Y].Sym == F_19 || Screen[X-1][Y].Sym == F_12 || Screen[X-1][Y].Sym == F_1E || Screen[X-1][Y].Sym == F_13) Count++; else { if (X - 1 == Compare_X && Y == Compare_Y) Count++; } if (Screen[X][Y-1].Sym == F_18 || Screen[X][Y-1].Sym == F_1D || Screen[X][Y-1].Sym == F_14 || Screen[X][Y-1].Sym == F_15 || Screen[X][Y-1].Sym == F_19 || Screen[X][Y-1].Sym == F_1E || Screen[X][Y-1].Sym == F_13) Count += 2; else { if (X == Compare_X && Y - 1 == Compare_Y) Count += 2; } if (Screen[X][Y+1].Sym == F_18 || Screen[X][Y+1].Sym == F_11 || Screen[X][Y+1].Sym == F_1C || Screen[X][Y+1].Sym == F_12 || Screen[X][Y+1].Sym == F_1D || Screen[X][Y+1].Sym == F_15 || Screen[X][Y+1].Sym == F_1E) Count += 4; else { if (X == Compare_X && Y + 1 == Compare_Y) Count += 4; } if (Screen[X+1][Y].Sym == F_1F || Screen[X+1][Y].Sym == F_11 || Screen[X+1][Y].Sym == F_1D || Screen[X+1][Y].Sym == F_14 || Screen[X+1][Y].Sym == F_1C || Screen[X+1][Y].Sym == F_15 || Screen[X+1][Y].Sym == F_19) Count += 8; else { if (X + 1 == Compare_X && Y == Compare_Y) Count += 8; } switch (Count) { case 0: /* Nothing */ break; case 1: case 8: case 9: Result = F_1F; break; case 2: case 4: case 6: Result = F_18; break; case 3: Result = F_11; break; case 5: Result = F_14; break; case 7: Result = F_1D; break; case 10: Result = F_12; break; case 11: Result = F_1C; break; case 12: Result = F_13; break; case 13: Result = F_19; break; case 14: Result = F_1E; break; case 15: Result = F_15; break; } return Result; } void Initialize_screen () { int X, Y; Died = 0; Level++; Sleep_Set ((17 - Level)*10000); /* .16 sec initially */ /* with the above value the game becomes unplayable around level 14 on * modern hardware (it was ok for a vt200 connected to a microvax....) * I depart from the original game here and use a smoother variation. --jmz */ Sleep_Set (170000 - Level*4000); for (X = 0; X < WIDTH; X++) { for (Y = 0; Y < HEIGHT; Y++) { Screen[X][Y].Sym = Blank; Screen[X][Y].Wall = Other; } } for (Y = 0; Y < HEIGHT; Y++) { Screen[0][Y].Sym = '.'; Screen[0][Y].Wall = Outside; Screen[WIDTH-1][Y].Sym = '.'; Screen[WIDTH-1][Y].Wall = Outside; } for (X = 0; X < WIDTH; X++) { Screen[X][0].Sym = '.'; Screen[X][0].Wall = Outside; Screen[X][HEIGHT-1].Sym = '.'; Screen[X][HEIGHT-1].Wall = Outside; } for (Y = 1; Y < HEIGHT-1; Y++) { Screen[1][Y].Sym = F_18; Screen[1][Y].Wall = Inside; Screen[WIDTH-2][Y].Sym = F_18; Screen[WIDTH-2][Y].Wall = Inside; } for (X = 1; X < WIDTH-1; X++) { Screen[X][1].Sym = F_1F; Screen[X][1].Wall = Inside; Screen[X][HEIGHT-2].Sym = F_1F; Screen[X][HEIGHT-2].Wall = Inside; } Screen[1][1].Sym = F_13; Screen[1][1].Wall = Inside; Screen[1][HEIGHT-2].Sym = F_12; Screen[1][HEIGHT-2].Wall = Inside; Screen[WIDTH-2][1].Sym = F_14; Screen[WIDTH-2][1].Wall = Inside; Screen[WIDTH-2][HEIGHT-2].Sym = F_11; Screen[WIDTH-2][HEIGHT-2].Wall = Inside; You_X = 1; You_Y = 1; Move_X = 0; Move_y = 1; Last_You_X = 2; Last_You_Y = 1; Dir_You = Clockwise; Snake_Head_X = 11; Snake_Head_Y = (HEIGHT-2)/2; Snake_Tail_X = Snake_Head_X; Snake_Tail_Y = Snake_Head_Y; Moves_since_stuck = 0; Screen[Snake_Head_X][Snake_Head_Y].Sym = Qix_Head; Screen[Snake_Head_X][Snake_Head_Y].Wall = Snake; Len_Snake = 0; Amt_Filled_In = 0; Moving_Extra_Greebly = 0; Snake_got_stuck = 0; Can_Create_wall = 0; Clock_Greeb_X = WIDTH-2; Clock_Greeb_y = (HEIGHT-2)/2; Last_Clock_Greeb_X = Clock_Greeb_X; Last_Clock_Greeb_y = Clock_Greeb_y + 1; Anti_Greeb_X = (WIDTH-2)/2; Anti_Greeb_y = HEIGHT-2; Last_Anti_Greeb_X = Anti_Greeb_X + 1; Last_Anti_Greeb_y = Anti_Greeb_y; Marked_Anti_Greeb = 0; Marked_Clock_Greeb = 0; Marked_Anti_Greeb_X = 0; Marked_Anti_Greeb_Y = 0; Marked_Clock_Greeb_X = 0; Marked_Clock_Greeb_Y = 0; Num_Moves_After_This_Pt = 9999; Creating_wall = 0; Draw_Screen (); } int Valid_Move (int X, int Y) { if (Screen[X][Y].Sym == '.') return 0; else { if (Screen[X][Y].Wall == Created) return 0; else return 1; } } void Move_Anti_Clockwise (int *X, int *Y, int *Last_X, int *Last_Y) { int Tmp_X, Tmp_Y; Tmp_X = *X; Tmp_Y = *Y; switch (*Last_Y - *Y) { case 1: switch (Screen[*X][*Y].Sym) { case F_13: (*X)++; break; case F_1E: (*X)++; break; case F_19: (*X)++; break; case F_15: (*X)++; break; case F_14: (*X)--; break; case F_1D: (*Y)--; break; case F_18: (*Y)--; break; } break; case 0: switch (*Last_X - *X) { case 1: switch (Screen[*X][*Y].Sym) { case F_13: (*Y)++; break; case F_1E: (*Y)--; break; case F_12: (*Y)--; break; case F_19: (*X)--; break; case F_15: (*Y)--; break; case F_1C: (*Y)--; break; case F_1F: (*X)--; break; } break; case 0: /* blank case */ break; case -1: switch (Screen[*X][*Y].Sym) { case F_19: (*Y)++; break; case F_15: (*Y)++; break; case F_1C: (*X)++; break; case F_14: (*Y)++; break; case F_1D: (*Y)++; break; case F_11: (*Y)--; break; case F_1F: (*X)++; break; } break; } break; case -1: switch (Screen[*X][*Y].Sym) { case F_1E: (*Y)++; break; case F_12: (*X)++; break; case F_15: (*X)--; break; case F_1C: (*X)--; break; case F_1D: (*X)--; break; case F_11: (*X)--; break; case F_18: (*Y)++; break; } break; } *Last_X = Tmp_X; *Last_Y = Tmp_Y; } void Move_Clockwise (int *X, int *Y, int *Last_X, int *Last_Y) { int Tmp_X, Tmp_Y; Tmp_X = *X; Tmp_Y = *Y; switch (*Last_Y - *Y) { case 1: switch (Screen[*X][*Y].Sym) { case F_13: (*X)++; break; case F_1E: (*Y)--; break; case F_19: (*X)--; break; case F_15: (*X)--; break; case F_14: (*X)--; break; case F_1D: (*X)--; break; case F_18: (*Y)--; break; } break; case 0: switch (*Last_X - *X) { case 1: switch (Screen[*X][*Y].Sym) { case F_13: (*Y)++; break; case F_1E: (*Y)++; break; case F_12: (*Y)--; break; case F_19: (*Y)++; break; case F_15: (*Y)++; break; case F_1C: (*X)--; break; case F_1F: (*X)--; break; } break; case 0: /* blank case */ break; case -1: switch (Screen[*X][*Y].Sym) { case F_19: (*X)++; break; case F_15: (*Y)--; break; case F_1C: (*Y)--; break; case F_14: (*Y)++; break; case F_1D: (*Y)--; break; case F_11: (*Y)--; break; case F_1F: (*X)++; break; } break; } break; case -1: switch (Screen[*X][*Y].Sym) { case F_1E: (*X)++; break; case F_12: (*X)++; break; case F_15: (*X)++; break; case F_1C: (*X)++; break; case F_1D: (*Y)++; break; case F_11: (*X)--; break; case F_18: (*Y)++; break; } break; } *Last_X = Tmp_X; *Last_Y = Tmp_Y; } void Move_Opp_Anti_Clockwise (int *X, int *Y, int *Last_X, int *Last_Y) { int Tmp_X, Tmp_Y; if (Screen[*X][*Y].Sym != F_15) { Move_Clockwise (X, Y, Last_X, Last_Y); return; } Tmp_X = *X; Tmp_Y = *Y; *Y += *Y - *Last_Y; *X += *X - *Last_X; *Last_X = Tmp_X; *Last_Y = Tmp_Y; } void Move_Opp_Clockwise (int *X, int *Y, int *Last_X, int *Last_Y) { int Tmp_X, Tmp_Y; if (Screen[*X][*Y].Sym != F_15) { Move_Anti_Clockwise (X, Y, Last_X, Last_Y); return; } Tmp_X = *X; Tmp_Y = *Y; *Y += *Y - *Last_Y; *X += *X - *Last_X; *Last_X = Tmp_X; *Last_Y = Tmp_Y; } void Jump_Greeb (int *Sudo_X, int *Sudo_Y, int *LSudo_X, int *LSudo_Y) { *Sudo_X = Snake_Head_X; *Sudo_Y = Snake_Head_Y; while (((1 << ((int)Screen[*Sudo_X][*Sudo_Y].Wall)) & ((1 << ((int)Created)) | (1 << ((int)Inside)))) == 0) (*Sudo_X)--; if (Screen[*Sudo_X][*Sudo_Y].Wall == Created) { *LSudo_X = *Sudo_X; *LSudo_Y = *Sudo_Y; switch (Screen[*Sudo_X][*Sudo_Y].Sym) { case F_14: case F_1D: case F_18: (*Sudo_Y)++; break; case F_11: (*Sudo_X)--; break; default: *LSudo_X = *Sudo_X + 1; *LSudo_Y = *Sudo_Y; break; } while (Screen[*Sudo_X][*Sudo_Y].Wall == Created) Move_Clockwise (Sudo_X, Sudo_Y, LSudo_X, LSudo_Y); return; } *LSudo_X = *Sudo_X; *LSudo_Y = *Sudo_Y; switch (Screen[*Sudo_X][*Sudo_Y].Sym) { case F_14: case F_1D: case F_18: (*Sudo_Y)++; break; case F_11: (*Sudo_X)--; break; default: *LSudo_X = *Sudo_X + 1; *LSudo_Y = *Sudo_Y; break; } } void Move_Greeblys () { int Tmp_; /*Move_Clockwise_wise_one*/ Pos (Clock_Greeb_X, Clock_Greeb_y, Screen[Clock_Greeb_X][Clock_Greeb_y].Sym); if (Screen[Clock_Greeb_X][Clock_Greeb_y].Wall == Inside) { if (Screen[Last_Clock_Greeb_X][Last_Clock_Greeb_y].Wall == Outside) { Marked_Clock_Greeb = 0; Move_Opp_Clockwise (&Clock_Greeb_X, &Clock_Greeb_y, &Last_Clock_Greeb_X, &Last_Clock_Greeb_y); } else { if (Marked_Clock_Greeb) { if (Num_Marked_Clock_Greeb > 80) { Marked_Clock_Greeb = 0; Move_Clockwise (&Clock_Greeb_X, &Clock_Greeb_y, &Last_Clock_Greeb_X, &Last_Clock_Greeb_y); } else { Num_Marked_Clock_Greeb++; if (Clock_Greeb_X == Marked_Clock_Greeb_X && Clock_Greeb_y == Marked_Clock_Greeb_Y) { Marked_Clock_Greeb = 0; Jump_Greeb (&Clock_Greeb_X, &Clock_Greeb_y, &Last_Clock_Greeb_X, &Last_Clock_Greeb_y); } else Move_Clockwise (&Clock_Greeb_X, &Clock_Greeb_y, &Last_Clock_Greeb_X, &Last_Clock_Greeb_y); } } else Move_Clockwise (&Clock_Greeb_X, &Clock_Greeb_y, &Last_Clock_Greeb_X, &Last_Clock_Greeb_y); } } else { if (Screen[Clock_Greeb_X][Clock_Greeb_y].Wall == Created) Move_Opp_Clockwise (&Clock_Greeb_X, &Clock_Greeb_y, &Last_Clock_Greeb_X, &Last_Clock_Greeb_y); else { if (Marked_Clock_Greeb) { if (Clock_Greeb_X == Marked_Clock_Greeb_X && Clock_Greeb_y == Marked_Clock_Greeb_Y) { Marked_Clock_Greeb = 0; Jump_Greeb (&Clock_Greeb_X, &Clock_Greeb_y, &Last_Clock_Greeb_X, &Last_Clock_Greeb_y); } else Move_Clockwise (&Clock_Greeb_X, &Clock_Greeb_y, &Last_Clock_Greeb_X, &Last_Clock_Greeb_y); } else Move_Clockwise (&Clock_Greeb_X, &Clock_Greeb_y, &Last_Clock_Greeb_X, &Last_Clock_Greeb_y); } } Pos (Clock_Greeb_X, Clock_Greeb_y, '*'); if (You_X == Clock_Greeb_X && You_Y == Clock_Greeb_y) Died = 1; /*Move AntiClockwise One */ Pos (Anti_Greeb_X, Anti_Greeb_y, Screen[Anti_Greeb_X][Anti_Greeb_y].Sym); if (Screen[Anti_Greeb_X][Anti_Greeb_y].Wall == Inside) { if (Screen[Last_Anti_Greeb_X][Last_Anti_Greeb_y].Wall == Outside) { Marked_Anti_Greeb = 0; Move_Opp_Anti_Clockwise (&Anti_Greeb_X, &Anti_Greeb_y, &Last_Anti_Greeb_X, &Last_Anti_Greeb_y); } else { if (Marked_Anti_Greeb) { if (Num_Marked_Anti_Greeb > 80) { Marked_Anti_Greeb = 0; Move_Anti_Clockwise (&Anti_Greeb_X, &Anti_Greeb_y, &Last_Anti_Greeb_X, &Last_Anti_Greeb_y); } else { Num_Marked_Anti_Greeb++; if (Anti_Greeb_X == Marked_Anti_Greeb_X && Anti_Greeb_y == Marked_Anti_Greeb_Y) { Marked_Anti_Greeb = 0; Jump_Greeb (&Anti_Greeb_X, &Anti_Greeb_y, &Last_Anti_Greeb_X, &Last_Anti_Greeb_y); Tmp_ = Anti_Greeb_X; Anti_Greeb_X = Last_Anti_Greeb_X; Last_Anti_Greeb_X = Tmp_; Tmp_ = Anti_Greeb_y; Anti_Greeb_y = Last_Anti_Greeb_y; Last_Anti_Greeb_y = Tmp_; } else Move_Anti_Clockwise (&Anti_Greeb_X, &Anti_Greeb_y, &Last_Anti_Greeb_X, &Last_Anti_Greeb_y); } } else Move_Anti_Clockwise (&Anti_Greeb_X, &Anti_Greeb_y, &Last_Anti_Greeb_X, &Last_Anti_Greeb_y); } } else { if (Screen[Anti_Greeb_X][Anti_Greeb_y].Wall == Created) Move_Opp_Anti_Clockwise (&Anti_Greeb_X, &Anti_Greeb_y, &Last_Anti_Greeb_X, &Last_Anti_Greeb_y); else { if (Marked_Anti_Greeb) { if (Anti_Greeb_X == Marked_Anti_Greeb_X && Anti_Greeb_y == Marked_Anti_Greeb_Y) { Marked_Anti_Greeb = 0; Jump_Greeb (&Anti_Greeb_X, &Anti_Greeb_y, &Last_Anti_Greeb_X, &Last_Anti_Greeb_y); Tmp_ = Anti_Greeb_X; Anti_Greeb_X = Last_Anti_Greeb_X; Last_Anti_Greeb_X = Tmp_; Tmp_ = Anti_Greeb_y; Anti_Greeb_y = Last_Anti_Greeb_y; Last_Anti_Greeb_y = Tmp_; } else Move_Anti_Clockwise (&Anti_Greeb_X, &Anti_Greeb_y, &Last_Anti_Greeb_X, &Last_Anti_Greeb_y); } else Move_Anti_Clockwise (&Anti_Greeb_X, &Anti_Greeb_y, &Last_Anti_Greeb_X, &Last_Anti_Greeb_y); } } Pos (Anti_Greeb_X, Anti_Greeb_y, '*'); if (You_X == Anti_Greeb_X && You_Y == Anti_Greeb_y) Died = 1; if (!Moving_Extra_Greebly) return; Pos (Extra_Greeb_X, Extra_Greeb_Y, Screen[Extra_Greeb_X][Extra_Greeb_Y].Sym); if (Dir_When_Start_Creat == Clockwise) Move_Clockwise (&Extra_Greeb_X, &Extra_Greeb_Y, &Last_Extra_Greeb_X, &Last_Extra_Greeb_Y); else Move_Anti_Clockwise (&Extra_Greeb_X, &Extra_Greeb_Y, &Last_Extra_Greeb_X, &Last_Extra_Greeb_Y); Pos (Extra_Greeb_X, Extra_Greeb_Y, '*'); if (You_X == Extra_Greeb_X && You_Y == Extra_Greeb_Y) { Died = 1; return; } Pos (Extra_Greeb_X, Extra_Greeb_Y, Screen[Extra_Greeb_X][Extra_Greeb_Y].Sym); if (Dir_When_Start_Creat == Clockwise) Move_Clockwise (&Extra_Greeb_X, &Extra_Greeb_Y, &Last_Extra_Greeb_X, &Last_Extra_Greeb_Y); else Move_Anti_Clockwise (&Extra_Greeb_X, &Extra_Greeb_Y, &Last_Extra_Greeb_X, &Last_Extra_Greeb_Y); Pos (Extra_Greeb_X, Extra_Greeb_Y, '*'); if (You_X == Extra_Greeb_X && You_Y == Extra_Greeb_Y) Died = 1; } /* Local variables for Move_Snake: */ struct LOC_Move_Snake { unsigned char Save_ch; int Swaped_head; int Dist_From_Tail; } ; /* Local variables for Get_Move_For_Snake: */ struct LOC_Get_Move_For_Snake { struct LOC_Move_Snake *LINK; } ; void Swap_snake_head_and_Tail (struct LOC_Get_Move_For_Snake *LINK) { int Tmp_Tail_X, Tmp_Tail_Y; LINK->LINK->Swaped_head = 1; Moves_since_stuck = 0; Snake_got_stuck = 0; Tmp_Tail_X = Snake_Tail_X; Tmp_Tail_Y = Snake_Tail_Y; Screen[Snake_Head_X][Snake_Head_Y].Wall = Other; Screen[Snake_Head_X][Snake_Head_Y].Sym = Blank; Pos (Snake_Head_X, Snake_Head_Y, Blank); if (Screen[Snake_Head_X][Snake_Head_Y+1].Wall == Snake && (Screen[Snake_Head_X][Snake_Head_Y+1].Sym == F_11 || Screen[Snake_Head_X][Snake_Head_Y+1].Sym == F_12 || Screen[Snake_Head_X][Snake_Head_Y+1].Sym == F_18)) { Snake_Tail_X = Snake_Head_X; Snake_Tail_Y = Snake_Head_Y + 1; } else { if (Screen[Snake_Head_X][Snake_Head_Y-1].Wall == Snake && (Screen[Snake_Head_X][Snake_Head_Y-1].Sym == F_14 || Screen[Snake_Head_X][Snake_Head_Y-1].Sym == F_13 || Screen[Snake_Head_X][Snake_Head_Y-1].Sym == F_18)) { Snake_Tail_X = Snake_Head_X; Snake_Tail_Y = Snake_Head_Y - 1; } else { if (Screen[Snake_Head_X+1][Snake_Head_Y].Wall == Snake && (Screen[Snake_Head_X+1][Snake_Head_Y].Sym == F_11 || Screen[Snake_Head_X+1][Snake_Head_Y].Sym == F_14 || Screen[Snake_Head_X+1][Snake_Head_Y].Sym == F_1F)) { Snake_Tail_X = Snake_Head_X + 1; Snake_Tail_Y = Snake_Head_Y; } else { if (Screen[Snake_Head_X-1][Snake_Head_Y].Wall == Snake && (Screen[Snake_Head_X-1][Snake_Head_Y].Sym == F_12 || Screen[Snake_Head_X-1][Snake_Head_Y].Sym == F_13 || Screen[Snake_Head_X-1][Snake_Head_Y].Sym == F_1F)) { Snake_Tail_X = Snake_Head_X - 1; Snake_Tail_Y = Snake_Head_Y; } } } } Snake_Head_X = Tmp_Tail_X; Snake_Head_Y = Tmp_Tail_Y; Screen[Snake_Head_X][Snake_Head_Y].Sym = Blank; Screen[Snake_Head_X][Snake_Head_Y].Wall = Snake; Pos (Snake_Head_X, Snake_Head_Y, Qix_Head); Len_Snake--; } int Sgn (int X) { if (X > 0) return 1; else { if (X < 0) return -1; else return 0; } } void Search_For_Move (struct LOC_Get_Move_For_Snake *LINK) { int X = 0, Y = 0; int XX, Dist; int Closest = 999999; int TEMP, TEMP1; Num_Snake_Searched++; Snake_Move_X = 0; Snake_Move_Y = 0; for (XX = 1; XX <= 4; XX++) { switch (XX) { case 1: Y = 1; break; case 2: Y = -1; break; case 3: Y = 0; X = 1; break; case 4: X = -1; break; } TEMP = Snake_Head_X + X - Snake_After_X; TEMP1 = Snake_Head_Y + Y - Snake_After_Y; Dist = TEMP * TEMP + TEMP1 * TEMP1; if (Dist < Closest) { if (X + Y != 0 && ((1 << ((int)Screen[Snake_Head_X + X][Snake_Head_Y + Y].Wall)) & ((1 << ((int)Created)) | (1 << ((int)Other)))) != 0 && (Snake_Head_X + X != Start_Creat_X || Snake_Head_Y + Y != Start_Creat_Y)) { Snake_Move_X = X; Snake_Move_Y = Y; Closest = Dist; } } } } void Get_Move_For_Snake (struct LOC_Move_Snake *LINK) { struct LOC_Get_Move_For_Snake V; int TEMP, TEMP1, TEMP2, TEMP3; V.LINK = LINK; if (Creating_wall) { if (Num_Snake_Searched > Rand (10) + 10 && Moves_since_stuck > 15) { Num_Snake_Searched = 0; Swap_snake_head_and_Tail (&V); Snake_After_X = You_X; Snake_After_Y = You_Y; } else { TEMP = Snake_Tail_X - Snake_After_X; TEMP1 = Snake_Head_Y - Snake_After_Y; LINK->Dist_From_Tail = TEMP * TEMP + TEMP1 * TEMP1; TEMP = Snake_Head_X - Snake_After_X; TEMP1 = Snake_Head_Y - Snake_After_Y; if (TEMP * TEMP + TEMP1 * TEMP1 > LINK->Dist_From_Tail * 2) { if (Moves_since_stuck > 10 && Len_Snake > 10 && LINK->Dist_From_Tail > 10) Swap_snake_head_and_Tail (&V); } TEMP = You_X - Snake_Head_X; TEMP1 = You_Y - Snake_Head_Y; TEMP2 = Snake_Head_X - Snake_After_X; TEMP3 = Snake_Head_Y - Snake_After_Y; if (TEMP * TEMP + TEMP1 * TEMP1 < TEMP2 * TEMP2 + TEMP3 * TEMP3) { Num_Snake_Searched = 0; Snake_After_X = You_X; Snake_After_Y = You_Y; } } } else { Num_Snake_Searched = 0; if (Num_Moves_After_This_Pt > Rand (10) + 10) { Snake_After_X = Rand (21); Snake_After_Y = Rand (78); Num_Moves_After_This_Pt = 0; } else Num_Moves_After_This_Pt++; } if (!Snake_got_stuck) { Snake_Move_X = 0; Snake_Move_Y = 0; if (Rand (4) == 1) { Snake_Move_X = Sgn (Snake_After_X - Snake_Head_X); if (Snake_Move_X == 0) Snake_Move_Y = Sgn (Snake_After_Y - Snake_Head_Y); } else { Snake_Move_Y = Sgn (Snake_After_Y - Snake_Head_Y); if (Snake_Move_Y == 0) Snake_Move_X = Sgn (Snake_After_X - Snake_Head_X); } if (Snake_Move_X + Snake_Move_Y == 0 || ((1 << ((int)Screen[Snake_Head_X + Snake_Move_X] [Snake_Head_Y + Snake_Move_Y].Wall)) & ((1 << ((int)Created)) | (1 << ((int)Other)))) == 0 || (Snake_Head_X + Snake_Move_X == Start_Creat_X && Snake_Head_Y + Snake_Move_Y == Start_Creat_Y)) Search_For_Move (&V); } else Search_For_Move (&V); if (Snake_Move_X == 0 && Snake_Move_Y == 0) { if (!Snake_got_stuck) { if (Moves_since_stuck > 10 && Len_Snake > 10) Swap_snake_head_and_Tail (&V); else { Len_Snake_When_Stuck = Len_Snake; Snake_got_stuck = 1; } } else { if (Len_Snake < Len_Snake_When_Stuck - 10 && Len_Snake > 10) { Swap_snake_head_and_Tail (&V); Moves_since_stuck = 0; Snake_got_stuck = 0; } } } else Snake_got_stuck = 0; Moves_since_stuck++; if (Screen[Snake_Head_X + Snake_Move_X][Snake_Head_Y + Snake_Move_Y].Wall == Created || (Snake_Head_X + Snake_Move_X == You_X && Snake_Head_Y + Snake_Move_Y == You_Y)) Died = 1; } void Remove_tail (struct LOC_Move_Snake *LINK) { if (!(Len_Snake >= MAX_LEN_SNAKE || Snake_got_stuck)) { Pos (Snake_Tail_X, Snake_Tail_Y, Screen[Snake_Tail_X][Snake_Tail_Y].Sym); return; } if (Snake_Tail_X != Snake_Head_X || Snake_Tail_Y != Snake_Head_Y) { Pos (Snake_Tail_X, Snake_Tail_Y, Blank); LINK->Save_ch = Screen[Snake_Tail_X][Snake_Tail_Y].Sym; Screen[Snake_Tail_X][Snake_Tail_Y].Sym = Blank; Screen[Snake_Tail_X][Snake_Tail_Y].Wall = Other; } if (Len_Snake <= 1) { Len_Snake = 1; Snake_Tail_X = Snake_Head_X; Snake_Tail_Y = Snake_Head_Y; } else { switch (LINK->Save_ch) { case F_13: if (Screen[Snake_Tail_X][Snake_Tail_Y+1].Sym == F_18 || Screen[Snake_Tail_X][Snake_Tail_Y+1].Sym == F_11 || Screen[Snake_Tail_X][Snake_Tail_Y+1].Sym == F_12) Snake_Tail_Y++; else Snake_Tail_X++; break; case F_12: if (Screen[Snake_Tail_X][Snake_Tail_Y-1].Sym == F_18 || Screen[Snake_Tail_X][Snake_Tail_Y-1].Sym == F_14 || Screen[Snake_Tail_X][Snake_Tail_Y-1].Sym == F_13) Snake_Tail_Y--; else Snake_Tail_X++; break; case F_14: if (Screen[Snake_Tail_X][Snake_Tail_Y+1].Sym == F_18 || Screen[Snake_Tail_X][Snake_Tail_Y+1].Sym == F_11 || Screen[Snake_Tail_X][Snake_Tail_Y+1].Sym == F_12) Snake_Tail_Y++; else Snake_Tail_X--; break; case F_11: if (Screen[Snake_Tail_X][Snake_Tail_Y-1].Sym == F_18 || Screen[Snake_Tail_X][Snake_Tail_Y-1].Sym == F_13 || Screen[Snake_Tail_X][Snake_Tail_Y-1].Sym == F_14) Snake_Tail_Y--; else Snake_Tail_X--; break; case F_1F: if (Screen[Snake_Tail_X-1][Snake_Tail_Y].Sym == F_1F || Screen[Snake_Tail_X-1][Snake_Tail_Y].Sym == F_12 || Screen[Snake_Tail_X-1][Snake_Tail_Y].Sym == F_13) Snake_Tail_X--; else Snake_Tail_X++; break; case F_18: if (Screen[Snake_Tail_X][Snake_Tail_Y-1].Sym == F_18 || Screen[Snake_Tail_X][Snake_Tail_Y-1].Sym == F_14 || Screen[Snake_Tail_X][Snake_Tail_Y-1].Sym == F_13) Snake_Tail_Y--; else Snake_Tail_Y++; break; case Blank: case '0': /* Nothing */ break; } } Len_Snake--; } /* remove_Tail*/ void Move_Snake () { struct LOC_Move_Snake V; V.Swaped_head = 0; Get_Move_For_Snake (&V); if (Snake_got_stuck) { Remove_tail (&V); Get_Move_For_Snake (&V); if (Snake_got_stuck) { Remove_tail (&V); Get_Move_For_Snake (&V); } } if (Snake_got_stuck || V.Swaped_head) return; V.Save_ch = Screen[Snake_Tail_X][Snake_Tail_Y].Sym; if (Len_Snake > 2) Screen[Snake_Tail_X][Snake_Tail_Y].Sym = '%'; Screen[Snake_Head_X][Snake_Head_Y].Wall = Snake; Screen[Snake_Head_X][Snake_Head_Y].Sym = Correct_Sym (Snake_Head_X, Snake_Head_Y, Snake_Head_X + Snake_Move_X, Snake_Head_Y + Snake_Move_Y); if ((Snake_Head_X != Snake_Tail_X || Snake_Head_Y != Snake_Tail_Y) && Len_Snake > 2) Screen[Snake_Tail_X][Snake_Tail_Y].Sym = V.Save_ch; Pos (Snake_Head_X, Snake_Head_Y, Screen[Snake_Head_X][Snake_Head_Y].Sym); Len_Snake++; Snake_Head_X += Snake_Move_X; Snake_Head_Y += Snake_Move_Y; Pos (Snake_Head_X, Snake_Head_Y, Qix_Head); Remove_tail (&V); } /* Local variables for Move_You: */ struct LOC_Move_You { int X, Y; } ; /* Local variables for Cal_Inside: */ struct LOC_Cal_Inside { struct LOC_Move_You *LINK; int Max_X, Min_X, Max_Y, Min_Y; } ; void Max_Or_Min (int X, int Y, struct LOC_Cal_Inside *LINK) { if (X > LINK->Max_X) LINK->Max_X = X; else { if (X < LINK->Min_X) LINK->Min_X = X; } if (Y > LINK->Max_Y) LINK->Max_Y = Y; else { if (Y < LINK->Min_Y) LINK->Min_Y = Y; } } void Cal_Inside (struct LOC_Move_You *LINK) { struct LOC_Cal_Inside V; int X, Y, Sudo_X, Sudo_Y, Lsudo_X, LSudo_Y; int Inside_Box, Written_something = 0; V.LINK = LINK; Sudo_X = Snake_Head_X; Sudo_Y = Snake_Head_Y; while (((1L << ((int)Screen[Sudo_X][Sudo_Y].Wall)) & ((1L << ((int)Created)) | (1L << ((int)Inside)))) == 0) Sudo_X--; if (Screen[Sudo_X][Sudo_Y].Wall == Created) { Lsudo_X = Sudo_X; LSudo_Y = Sudo_Y; switch (Screen[Sudo_X][Sudo_Y].Sym) { case F_14: case F_1D: case F_18: Sudo_Y++; break; case F_11: Sudo_X--; break; } while (Screen[Sudo_X][Sudo_Y].Wall == Created) Move_Clockwise (&Sudo_X, &Sudo_Y, &Lsudo_X, &LSudo_Y); } else { Lsudo_X = Sudo_X; LSudo_Y = Sudo_Y; switch (Screen[Sudo_X][Sudo_Y].Sym) { case F_14: case F_1D: case F_18: Sudo_Y++; break; case F_11: Sudo_X--; break; } } while (Screen[Sudo_X][Sudo_Y].Wall != Created) Move_Clockwise (&Sudo_X, &Sudo_Y, &Lsudo_X, &LSudo_Y); Sleep (0, 250000); if (Sudo_X == Start_Creat_X && Sudo_Y == Start_Creat_Y) Dir_You = Clockwise; else Dir_You = AntiClockwise; Move_Opp_Clockwise (&Sudo_X, &Sudo_Y, &Lsudo_X, &LSudo_Y); V.Min_X = 9999; V.Min_Y = 9999; V.Max_X = -9999; V.Max_Y = -9999; while (Screen[Sudo_X][Sudo_Y].Wall != Created) { Screen[Sudo_X][Sudo_Y].Wall = Tmp; if (Screen[Sudo_X][Sudo_Y].Sym == F_12) { if (Lsudo_X == Sudo_X + 1) Screen[Sudo_X][Sudo_Y].Wall = TmpN; } else { if (Screen[Sudo_X][Sudo_Y].Sym == F_11) { if (LSudo_Y == Sudo_Y - 1) Screen[Sudo_X][Sudo_Y].Wall = TmpN; } else { if (Screen[Sudo_X][Sudo_Y].Sym == F_1C) { if (Lsudo_X == Sudo_X + 1) Screen[Sudo_X][Sudo_Y].Wall = TmpN; } } } Move_Clockwise (&Sudo_X, &Sudo_Y, &Lsudo_X, &LSudo_Y); Max_Or_Min (Sudo_X, Sudo_Y, &V); } Sleep (0, 250000); while (Screen[Sudo_X][Sudo_Y].Wall == Created) { Screen[Sudo_X][Sudo_Y].Wall = TmpCreat; if (Screen[Sudo_X][Sudo_Y].Sym == F_12) { if (Lsudo_X == Sudo_X + 1) Screen[Sudo_X][Sudo_Y].Wall = TmpN2; } else { if (Screen[Sudo_X][Sudo_Y].Sym == F_11) { if (LSudo_Y == Sudo_Y - 1) Screen[Sudo_X][Sudo_Y].Wall = TmpN2; } else { if (Screen[Sudo_X][Sudo_Y].Sym == F_1C) { if (Lsudo_X == Sudo_X + 1) Screen[Sudo_X][Sudo_Y].Wall = TmpN2; } } } Max_Or_Min (Sudo_X, Sudo_Y, &V); Move_Clockwise (&Sudo_X, &Sudo_Y, &Lsudo_X, &LSudo_Y); } Sleep (0, 250000); VT_fill_start (); for (X = V.Min_X; X <= V.Max_X; X++) { Inside_Box = 0; for (Y = V.Min_Y; Y <= V.Max_Y; Y++) { if (((1 << ((int)Screen[X][Y].Wall)) & ((1 << ((int)Inside)) | (1 << ((int)Outside)) | (1 << ((int)Snake)) | (1 << ((int)Other)))) == 0) { if (Screen[X][Y].Sym == F_19 || Screen[X][Y].Sym == F_1F) { if (Inside_Box) { Written_something = 0; Inside_Box = 0; } else Inside_Box = 1; } else { if (Screen[X][Y].Sym == F_1C || Screen[X][Y].Sym == F_11 || Screen[X][Y].Sym == F_12) { if (((1L << ((int)Screen[X][Y].Wall)) & ((1L << ((int)TmpN)) | (1L << ((int)TmpN2)))) == 0) { Written_something = 0; Inside_Box = 0; } else Inside_Box = 1; } else { if (Written_something) { Written_something = 0; Inside_Box = 0; } else Inside_Box = 1; } } } else { if (Inside_Box && Screen[X][Y].Wall == Other) { Amt_Filled_In++; if (!Written_something) { Pos (X, Y, Blank); Written_something = 1; } else Pos (X, Y, Blank); Screen[X][Y].Wall = Outside; } else { Inside_Box = 0; Written_something = 0; } } } } VT_fill_end (); while (((1 << ((int)Screen[Sudo_X][Sudo_Y].Wall)) & ((1 << ((int)Tmp)) | (1 << ((int)TmpN)))) != 0) { Screen[Sudo_X][Sudo_Y].Wall = Outside; Max_Or_Min (Sudo_X, Sudo_Y, &V); Move_Clockwise (&Sudo_X, &Sudo_Y, &Lsudo_X, &LSudo_Y); } Amt_Filled_In -= 2; while (((1 << ((int)Screen[Sudo_X][Sudo_Y].Wall)) & ((1 << ((int)TmpCreat)) | (1 << ((int)Created)) | (1L << ((int)TmpN2)))) != 0) { Amt_Filled_In++; Screen[Sudo_X][Sudo_Y].Wall = Inside; Max_Or_Min (Sudo_X, Sudo_Y, &V); Move_Clockwise (&Sudo_X, &Sudo_Y, &Lsudo_X, &LSudo_Y); } if (!Marked_Clock_Greeb || Num_Marked_Clock_Greeb > 0) { /* > 0 If Marked When Inside */ Marked_Clock_Greeb = 1; Marked_Clock_Greeb_X = Last_Clock_Greeb_X; Marked_Clock_Greeb_Y = Last_Clock_Greeb_y; Num_Marked_Clock_Greeb = 0; } if (Marked_Anti_Greeb && Num_Marked_Anti_Greeb <= 0) return; Marked_Anti_Greeb = 0; Marked_Anti_Greeb_X = Last_Anti_Greeb_X; Marked_Anti_Greeb_Y = Last_Anti_Greeb_y; Num_Marked_Anti_Greeb = 0; } int VAlid_MOve_Clockwise (int X, int Y, int LX, int LY, int NX, int NY) { Move_Clockwise (&X, &Y, &LX, &LY); if (X == NX && Y == NY) return 1; else return 0; } int VAlid_MOve_Anti_Clockwise (int X, int Y, int LX, int LY, int NX, int NY) { Move_Anti_Clockwise (&X, &Y, &LX, &LY); if (X == NX && Y == NY) return 1; else return 0; } int Valid_MOve (struct LOC_Move_You *LINK) { if (You_X == Last_You_X && You_Y == Last_You_Y) { if (Dir_You == Clockwise) Dir_You = AntiClockwise; else Dir_You = Clockwise; return 1; } else { if (Dir_You == Clockwise) { if (VAlid_MOve_Clockwise (LINK->X, LINK->Y, Last_You_X, Last_You_Y, You_X, You_Y)) return 1; else return 0; } else { if (VAlid_MOve_Anti_Clockwise (LINK->X, LINK->Y, Last_You_X, Last_You_Y, You_X, You_Y)) return 1; else return 0; } } } void Move_You () { struct LOC_Move_You V; char save_ch; save_ch = Screen[Snake_Tail_X][Snake_Tail_Y].Sym; if (Len_Snake > 2) Screen[Snake_Tail_X][Snake_Tail_Y].Sym = '%'; V.X = You_X; V.Y = You_Y; You_X += Move_X; You_Y += Move_y; switch (Screen[You_X][You_Y].Wall) { case Other: if (Can_Create_wall) { if (!Creating_wall) { Moves_since_stuck = 999; Snake_After_X = 9999; Snake_After_Y = 9999; Start_Creat_X = V.X; Start_Creat_Y = V.Y; Last_Start_Creat_X = Last_You_X; Last_Start_Creat_Y = Last_You_Y; Dir_When_Start_Creat = Dir_You; } Screen[V.X][V.Y].Sym = Correct_Sym (V.X, V.Y, You_X, You_Y); Screen[V.X][V.Y].Wall = Created; Creating_wall = 1; Last_You_X = V.X; Last_You_Y = V.Y; } else { You_X = V.X; You_Y = V.Y; } break; case Snake: if (Can_Create_wall) { Died = 1; if (!Creating_wall) { Snake_After_X = 9999; Snake_After_Y = 9999; Start_Creat_X = V.X; Start_Creat_Y = V.Y; Last_Start_Creat_X = Last_You_X; Last_Start_Creat_Y = Last_You_Y; Dir_When_Start_Creat = Dir_You; } Screen[V.X][V.Y].Sym = Correct_Sym (V.X, V.Y, You_X, You_Y); Screen[V.X][V.Y].Wall = Created; Creating_wall = 1; Last_You_X = V.X; Last_You_Y = V.Y; } else { You_X = V.X; You_Y = V.Y; } break; case Inside: if (Creating_wall) { /* Have Created A Box */ Creating_wall = 0; Can_Create_wall = 0; Screen[V.X][V.Y].Sym = Correct_Sym (V.X, V.Y, You_X, You_Y); Screen[V.X][V.Y].Wall = Created; Pos (V.X, V.Y, Screen[V.X][V.Y].Sym); Pos (You_X, You_Y, You); Screen[You_X][You_Y].Sym = Correct_Sym (You_X, You_Y, You_X, You_Y); Screen[You_X][You_Y].Wall = Created; Cal_Inside (&V); if (Moving_Extra_Greebly) Pos (Extra_Greeb_X, Extra_Greeb_Y, Screen[Extra_Greeb_X][Extra_Greeb_Y].Sym); Moving_Extra_Greebly = 0; if (Amt_Filled_In > .75*(WIDTH-4)*(HEIGHT-4)) { float f; f = Amt_Filled_In * 100.0 / ((WIDTH-4)*(HEIGHT-4)); Score += 2 * 16.38 *f - 1228; VT_covered (f); VT_score (Score); Sleep (3, 0); Initialize_screen (); } else { float f; int a; f = Amt_Filled_In * 100.0 / ((WIDTH-4)*(HEIGHT-4)); a = f * 16.38; VT_covered (f); VT_score (Score+a); Last_You_X = V.X; Last_You_Y = V.Y; } } else { if (!Valid_MOve (&V)) { You_X = V.X; You_Y = V.Y; } else { Last_You_X = V.X; Last_You_Y = V.Y; } } break; case Created: if (!Moving_Extra_Greebly) { Moving_Extra_Greebly = 1; Extra_Greeb_X = Start_Creat_X; Extra_Greeb_Y = Start_Creat_Y; Last_Extra_Greeb_X = Last_Start_Creat_X; Last_Extra_Greeb_Y = Last_Start_Creat_Y; Pos (Extra_Greeb_X, Extra_Greeb_Y, '*'); } You_X = V.X; You_Y = V.Y; break; case Outside: You_X = V.X; You_Y = V.Y; break; default: break; } if ((You_X == Snake_Head_X && You_Y == Snake_Head_Y) || (You_X == Clock_Greeb_X && You_Y == Clock_Greeb_y) || (You_X == Anti_Greeb_X && You_Y == Anti_Greeb_y)) Died = 1; if (Len_Snake > 2) Screen[Snake_Tail_X][Snake_Tail_Y].Sym = save_ch; Pos (V.X, V.Y, Screen[V.X][V.Y].Sym); Pos (You_X, You_Y, You); } int Get_move () { switch (VT_getchar ()) { case K_PAUSE: VT_pause (); break; case K_WALL: Can_Create_wall = 1; break; case K_LEFT: Move_X = 0; Move_y = -1; break; case K_RIGHT: Move_X = 0; Move_y = 1; break; case K_UP: Move_y = 0; Move_X = -1; break; case K_DOWN: Move_y = 0; Move_X = 1; break; case K_EXIT: return 0; break; } return 1; } void Have_Died () { int Dummy, LSudo_X, LSudo_Y, Sudo_X, Sudo_Y; char Save_Sym; Died = 0; Lives--; VT_beep (); if (Lives <= 0) return; if (Creating_wall) { if (Moving_Extra_Greebly) Pos (Extra_Greeb_X, Extra_Greeb_Y, Screen[Extra_Greeb_X][Extra_Greeb_Y].Sym); Moving_Extra_Greebly = 0; Save_Sym = Screen[Snake_Tail_X][Snake_Tail_Y].Sym; Sudo_X = Last_You_X; Sudo_Y = Last_You_Y; LSudo_X = You_X; LSudo_Y = You_Y; Pos (LSudo_X, LSudo_Y, Screen[You_X][You_Y].Sym); Move_Clockwise (&Sudo_X, &Sudo_Y, &LSudo_X, &LSudo_Y); while (Screen[Sudo_X][Sudo_Y].Wall != Inside) { Pos (LSudo_X, LSudo_Y, Blank); Screen[LSudo_X][LSudo_Y].Sym = Blank; Screen[LSudo_X][LSudo_Y].Wall = Other; Move_Clockwise (&Sudo_X, &Sudo_Y, &LSudo_X, &LSudo_Y); } Creating_wall = 0; if (Snake_Head_X != Snake_Tail_X || Snake_Head_Y != Snake_Tail_Y) Screen[Snake_Tail_X][Snake_Tail_Y].Sym = '%'; Screen[LSudo_X][LSudo_Y].Sym = Correct_Sym (LSudo_X, LSudo_Y, LSudo_X, LSudo_Y); if (Snake_Head_X != Snake_Tail_X || Snake_Head_Y != Snake_Tail_Y) Screen[Snake_Tail_X][Snake_Tail_Y].Sym = Save_Sym; Screen[LSudo_X][LSudo_Y].Wall = Inside; Pos (LSudo_X, LSudo_Y, Screen[LSudo_X][LSudo_Y].Sym); You_X = Start_Creat_X; You_Y = Start_Creat_Y; Last_You_X = Last_Start_Creat_X; Last_You_Y = Last_Start_Creat_Y; Dir_You = Dir_When_Start_Creat; } Pos (Snake_Head_X, Snake_Head_Y, Qix_Head); Pos (You_X, You_Y, You); Pos (Clock_Greeb_X, Clock_Greeb_y, Screen[Clock_Greeb_X][Clock_Greeb_y].Sym); Pos (Anti_Greeb_X, Anti_Greeb_y, Screen[Anti_Greeb_X][Anti_Greeb_y].Sym); VT_lives (Lives); Can_Create_wall = 0; for (Dummy = 1; Dummy <= 4; Dummy++) Move_Greeblys (); } int leave () { VT_clear (); Score += Amt_Filled_In * 1638 /((WIDTH-4)*(HEIGHT-4)); TopTen (Score, Level); return terminate (0); } int double_speed = 0; void qix (int level) { int i; Screen = (struct Char_On_Screen **) malloc (WIDTH*sizeof (struct Char_On_Screen *)); for (i = 0; i < HEIGHT; i++) Screen[i] = (struct Char_On_Screen *) malloc (HEIGHT*sizeof (struct Char_On_Screen)); do { VT_init (); Help_Screen (); Level = level; Lives = 3; Score = 0; Initialize_screen (); i = 0; do { Sleep_Start (); if (!Get_move ()) break; Move_You (); if (!Died) { Move_Snake (); Move_Greeblys (); if (Rand (Level) >= 4 && !Died) { Move_Greeblys (); if (Rand (Level) >= 5 && !Died) { Move_Snake (); if (Rand (Level) >= 6 && !Died) { Move_Greeblys (); if (Rand (Level) >= 7 && !Died) { Move_Snake (); if (Rand (Level) >= 8 && !Died) { Move_Greeblys (); if (Rand (Level) >= 9 && !Died) Move_Snake (); } } } } } } Sleep_Wait (); if (Died) Have_Died (); } while (Lives > 0); } while (!leave ()); } int sleep_time; struct timeval tp; void Sleep_Set (int time) { sleep_time = time; } void Sleep_Start () { gettimeofday (&tp, 0); } #if 0 void Sleep_Wait () { /* returns if time elapsed since Sleep_Set() is > sleep_time. Otherwise * sleep until sleep_time is elapsed */ struct timeval t; int s; gettimeofday (&t, 0); s = 1000000* (t.tv_sec - tp.tv_sec); if (s > 1) return; s += (t.tv_usec - tp.tv_usec); if (s > sleep_time) return; s = sleep_time - s; usleep (s); } #else void Sleep_Wait () { /* returns if time elapsed since Sleep_Set() is > sleep_time. Otherwise * sleep until sleep_time is elapsed */ struct timeval t; int s; gettimeofday (&t, 0); if (t.tv_sec - tp.tv_sec > 1) return; while (1) { gettimeofday (&t, 0); s = 1000000* (t.tv_sec - tp.tv_sec); s += (t.tv_usec - tp.tv_usec); if (double_speed) s += s; if (s > sleep_time) break; } } #endif void Sleep (int sec, int usec) { if (sec) sleep (sec); else usleep (usec); }