Computer Science Canada

Snake Game

Author:  LiquidDragon [ Fri May 14, 2004 5:38 pm ]
Post subject:  Snake Game

Well it seems to be alomst the end of the year and our teachers are beginning to assign the end of the year projects. For mine i have decided to make a snake game Dance. My teacher was suprised that i wanted to take the "challenge" although i dont find it to challenging myself. Just difficult to increase the length of the snake.

If you have been assigned your end of the year project feel free to post it or tell me what its about because i would like to no.

I will also update you on my progress for my snake game, but it will be pretty basic because of the basic knowledge our teacher taught us.

Author:  LiquidDragon [ Fri May 14, 2004 6:20 pm ]
Post subject: 

Ok i have some problems so far. i need to get my oranges (the things the snake collects) to be on some sort of grid so the snake will get it in line

Here is my code:

code:

setscreen ("graphics:640;480")

proc snake_up (var x, y : int)

    drawfillbox (x - 10, y, x + 10, y - 30, 0)
    drawfilloval (x, y, 10, 10, 12)

end snake_up

proc snake_down (var x, y : int)

    drawfillbox (x - 10, y, x + 10, y + 30, 0)
    drawfilloval (x, y, 10, 10, 12)

end snake_down

proc snake_left (var x, y : int)

    drawfillbox (x, y - 10, x + 30, y + 10, 0)
    drawfilloval (x, y, 10, 10, 12)

end snake_left

proc snake_right (var x, y : int)

    drawfillbox (x, y - 10, x - 30, y + 10, 0)
    drawfilloval (x, y, 10, 10, 12)

end snake_right

%boundaries
drawfillbox (115, 40, 128, 440, 7) %left wall
drawfillbox (120, 430, 520, 440, 7) %top wall
drawfillbox (511, 40, 520, 440, 7) %right wall
drawfillbox (114, 35, 520, 48, 7) %bottom wall

var x, y : int
var key : string (1)
var orange_x, orange_y : int

x := maxx div 2
y := maxy div 2

randint (orange_x, 150, 510)
randint (orange_y, 50, 430)

loop
    getch (key)

    %drawing the orange
    drawfilloval (orange_x, orange_y, 10, 10, 8)

    if key = KEY_UP_ARROW and whatdotcolor (x, y + 20) not= 7 then
        y += 20
        snake_up (x, y)
    elsif key = KEY_DOWN_ARROW and whatdotcolor (x, y - 20) not= 7 then
        y -= 20
        snake_down (x, y)
    elsif key = KEY_LEFT_ARROW and whatdotcolor (x - 20, y) not= 7 then
        x -= 20
        snake_left (x, y)
    elsif key = KEY_RIGHT_ARROW and whatdotcolor (x + 20, y) not= 7 then
        x += 20
        snake_right (x, y)
    end if
end loop

Author:  gamer [ Fri May 14, 2004 7:23 pm ]
Post subject: 

dont use getch , use Input.KeyDown instead

Author:  Tony [ Fri May 14, 2004 9:56 pm ]
Post subject: 

first of all this belongs in [turing help]

second - maybe you should take a look at an existing snake. Maybe you'll get some ideas for variables setup and types of procedures needed.

Don't copy though, cuz that would be apparent

Author:  LiquidDragon [ Sat May 15, 2004 8:30 am ]
Post subject: 

see the problem is i cant use Input.KeyDown becuase we have never learned that in class, so my teacher will get angry. Although i dont understand why Hit Wall She also said that if she finds something we havent learned it will be considered "cheating" and can't have cheating Naughty. So i have to keep it simple.

Well... i can add Input.KeyDown if someone explained how it worked and then i could explain to the teacher Smile

Author:  MyPistolsIn3D [ Sat May 15, 2004 12:48 pm ]
Post subject: 

Tpye Input.KeyDown in a turing window and press F9.

Author:  white_dragon [ Sat May 15, 2004 4:27 pm ]
Post subject: 

it basically lets u use more than one key at a time. though i think there is a limit to how many keys u can use.

Author:  LiquidDragon [ Sat May 15, 2004 6:17 pm ]
Post subject: 

Ok well im gonna stick with the getch because otherwise it gets all weird. So now i have two problems

1. When my snake eats an orange he increases in length. I have tried many things for this but haven't figured it out.

2. getting the orange to be on the same grid as the snake. Right now the snake isnt technically on a grid it just looks like it because i set the x and y increases to 20.

Here is what i have so far
code:

setscreen ("graphics:640;480")

var snake_length : int

snake_length := 1

proc snake_up (var x, y : int)

    drawfillbox (x - 10, y, x + 10, y - 30, 0)
    drawfilloval (x, y, 10, 10, 12)

end snake_up

proc snake_down (var x, y : int)

    drawfillbox (x - 10, y, x + 10, y + 30, 0)
    drawfilloval (x, y, 10, 10, 12)

end snake_down

proc snake_left (var x, y : int)

    drawfillbox (x, y - 10, x + 30, y + 10, 0)
    drawfilloval (x, y, 10, 10, 12)

end snake_left

proc snake_right (var x, y : int)

    drawfillbox (x, y - 10, x - 30, y + 10, 0)
    drawfilloval (x, y, 10, 10, 12)

end snake_right

%boundaries
drawfillbox (115, 40, 128, 440, 7) %left wall
drawfillbox (120, 430, 520, 440, 7) %top wall
drawfillbox (511, 40, 520, 440, 7) %right wall
drawfillbox (114, 35, 520, 48, 7) %bottom wall

var x, y : int
var key : string (1)
var orange_x, orange_y : int

x := maxx div 2
y := maxy div 2

randint (orange_x, 150, 510)
randint (orange_y, 50, 430)

loop
    getch (key)

    %drawing the orange
    drawfilloval (orange_x, orange_y, 10, 10, 9)

    if key = KEY_UP_ARROW and whatdotcolor (x, y + 20) not= 7 then
        y += 20
        snake_up (x, y)
    elsif key = KEY_DOWN_ARROW and whatdotcolor (x, y - 20) not= 7 then
        y -= 20
        snake_down (x, y)
    elsif key = KEY_LEFT_ARROW and whatdotcolor (x - 20, y) not= 7 then
        x -= 20
        snake_left (x, y)
    elsif key = KEY_RIGHT_ARROW and whatdotcolor (x + 20, y) not= 7 then
        x += 20
        snake_right (x, y)
    end if
end loop

Author:  SuperGenius [ Sat May 15, 2004 9:56 pm ]
Post subject: 

If you are making a snake game you really need to have at least a few shapes in a 'train' to start with. In the real snake, the head is controlled by the user and each trailing piece will turn in the same direction at the same location that the head did. Also, if you do this you're going to have to add collision detection to see if the snake has run over itself.

Author:  LiquidDragon [ Sun May 16, 2004 9:33 am ]
Post subject: 

Yes i am still working on all that but one small bit at a time.

Author:  LiquidDragon [ Sun May 16, 2004 10:31 am ]
Post subject: 

Ok so i got the snake to follow me but now it tends to leave ovals behind when i switch directions. Could someone help me out with that and maybe help me with Input.KeyDown like give an exmaple in my program.



code:

setscreen ("graphics:640;480")

var snake_length : int

snake_length := 4

proc snake_up (var x, y : int)

    drawfillbox (x - 10, y, x + 10, y - 30, 0)
    drawfilloval (x, y, 10, 10, 12)
    drawfilloval (x - 4, y + 4, 2, 2, green)
    drawfilloval (x + 4, y + 4, 2, 2, green)

end snake_up

proc snake_up_f (var x, y : int)

    if whatdotcolor (x, y - (20 * snake_length)) not= 7 then
        drawfilloval (x, y - (20 * snake_length), 10, 10, 0)
    end if
    drawfilloval (x, y - 20, 10, 10, 12)

end snake_up_f

proc snake_down (var x, y : int)

    drawfillbox (x - 10, y, x + 10, y + 30, 0)
    drawfilloval (x, y, 10, 10, 12)
    drawfilloval (x - 4, y - 4, 2, 2, green)
    drawfilloval (x + 4, y - 4, 2, 2, green)

end snake_down

proc snake_down_f (var x, y : int)

    if whatdotcolor (x, y + (20 * snake_length)) not= 7 then
        drawfilloval (x, y + (20 * snake_length), 10, 10, 0)
    end if
    drawfilloval (x, y + 20, 10, 10, 12)

end snake_down_f

proc snake_left (var x, y : int)

    drawfillbox (x, y - 10, x + 30, y + 10, 0)
    drawfilloval (x, y, 10, 10, 12)
    drawfilloval (x - 4, y + 4, 2, 2, green)
    drawfilloval (x - 4, y - 4, 2, 2, green)

end snake_left

proc snake_left_f (var x, y : int)

    if whatdotcolor (x + (20 * snake_length), y) not= 7 then
        drawfilloval (x + (20 * snake_length), y, 10, 10, 0)
    end if
    drawfilloval (x + 20, y, 10, 10, 12)

end snake_left_f

proc snake_right (var x, y : int)

    drawfillbox (x, y - 10, x - 30, y + 10, 0)
    drawfilloval (x, y, 10, 10, 12)
    drawfilloval (x + 4, y + 4, 2, 2, green)
    drawfilloval (x + 4, y - 4, 2, 2, green)

end snake_right

proc snake_right_f (var x, y : int)

    if whatdotcolor (x - (20 * snake_length), y) not= 7 then
        drawfilloval (x - (20 * snake_length), y, 10, 10, 0)
    end if
    drawfilloval (x - 20, y, 10, 10, 12)

end snake_right_f


%boundaries
drawfillbox (115, 40, 128, 440, 7)     %left wall
drawfillbox (120, 430, 520, 440, 7)     %top wall
drawfillbox (511, 40, 520, 440, 7)     %right wall
drawfillbox (114, 35, 520, 48, 7)     %bottom wall

var x, y : int
var key : string (1)
var orange_x, orange_y : int

x := maxx div 2
y := maxy div 2

randint (orange_x, 150, 510)
randint (orange_y, 50, 430)

loop
    getch (key)

    %drawing the orange
    drawfilloval (orange_x, orange_y, 10, 10, 9)

    if key = KEY_UP_ARROW and whatdotcolor (x, y + 20) not= 7 then
        y += 20
        snake_up (x, y)
        for i : 1 .. snake_length
            snake_up_f (x, y)
        end for
    elsif key = KEY_DOWN_ARROW and whatdotcolor (x, y - 20) not= 7 then
        y -= 20
        snake_down (x, y)
        for i : 1 .. snake_length
            snake_down_f (x, y)
        end for
    elsif key = KEY_LEFT_ARROW and whatdotcolor (x - 20, y) not= 7 then
        x -= 20
        snake_left (x, y)
        for i : 1 .. snake_length
            snake_left_f (x, y)
        end for
    elsif key = KEY_RIGHT_ARROW and whatdotcolor (x + 20, y) not= 7 then
        x += 20
        snake_right (x, y)
        for i : 1 .. snake_length
            snake_right_f (x, y)
        end for
    end if
end loop

Author:  LiquidDragon [ Sun May 16, 2004 3:18 pm ]
Post subject: 

Come on i really need help on this. I just need to know how to make the circles follow behind. I can do it but as soon as i change directions it messes up.

Author:  LiquidDragon [ Sun May 16, 2004 3:38 pm ]
Post subject: 

YAY!!!! I finally got it to work. Now its time for collision detection and stuff. I'm so happy i finally got it Dance Dance Dance Dance

Look how i got it to work

code:

setscreen ("graphics:640;480")

var snake_length : int

snake_length := 4

proc snake_up (var x, y : int)

    drawfillbox (x - 10, y, x + 10, y - 30, 0)
    drawfilloval (x, y, 10, 10, 12)
    drawfilloval (x - 4, y + 4, 2, 2, green)
    drawfilloval (x + 4, y + 4, 2, 2, green)

end snake_up

proc snake_up_f (var x, y : int)

    drawfilloval (x, y - 20, 10, 10, 12)

end snake_up_f

proc snake_down (var x, y : int)

    drawfillbox (x - 10, y, x + 10, y + 30, 0)
    drawfilloval (x, y, 10, 10, 12)
    drawfilloval (x - 4, y - 4, 2, 2, green)
    drawfilloval (x + 4, y - 4, 2, 2, green)

end snake_down

proc snake_down_f (var x, y : int)

    drawfilloval (x, y + 20, 10, 10, 12)

end snake_down_f

proc snake_left (var x, y : int)

    drawfillbox (x, y - 10, x + 30, y + 10, 0)
    drawfilloval (x, y, 10, 10, 12)
    drawfilloval (x - 4, y + 4, 2, 2, green)
    drawfilloval (x - 4, y - 4, 2, 2, green)

end snake_left

proc snake_left_f (var x, y : int)

    drawfilloval (x + 20, y, 10, 10, 12)

end snake_left_f

proc snake_right (var x, y : int)

    drawfillbox (x, y - 10, x - 30, y + 10, 0)
    drawfilloval (x, y, 10, 10, 12)
    drawfilloval (x + 4, y + 4, 2, 2, green)
    drawfilloval (x + 4, y - 4, 2, 2, green)

end snake_right

proc snake_right_f (var x, y : int)

    drawfilloval (x - 20, y, 10, 10, 12)

end snake_right_f


%boundaries
drawfillbox (115, 40, 128, 440, 7)     %left wall
drawfillbox (120, 430, 520, 440, 7)     %top wall
drawfillbox (511, 40, 520, 440, 7)     %right wall
drawfillbox (114, 35, 520, 48, 7)     %bottom wall

var x, y : int
var key : string (1)
var count : int
var orange_x, orange_y : int
var erase_x, erase_y : array 1 .. 1000 of int

x := maxx div 2
y := maxy div 2

count := 0

randint (orange_x, 150, 510)
randint (orange_y, 50, 430)

loop
    getch (key)

    count += 1

    erase_x (count) := x
    erase_y (count) := y

    %drawing the orange
    drawfilloval (orange_x, orange_y, 10, 10, 9)

    if key = KEY_UP_ARROW and whatdotcolor (x, y + 20) not= 7 then

        y += 20
        snake_up (x, y)
        snake_up_f (x, y)

    elsif key = KEY_DOWN_ARROW and whatdotcolor (x, y - 20) not= 7 then

        y -= 20
        snake_down (x, y)
        snake_down_f (x, y)

    elsif key = KEY_LEFT_ARROW and whatdotcolor (x - 20, y) not= 7 then

        x -= 20
        snake_left (x, y)
        snake_left_f (x, y)

    elsif key = KEY_RIGHT_ARROW and whatdotcolor (x + 20, y) not= 7 then

        x += 20
        snake_right (x, y)
        snake_right_f (x, y)
    end if

%This erases the last part of the snake :D
    if count >= snake_length then
        drawfilloval (erase_x (count - snake_length + 1), erase_y (count - snake_length + 1), 10, 10, 0)
    end if

end loop


I think some bits are in order Laughing

Author:  white_dragon [ Sun May 16, 2004 4:54 pm ]
Post subject: 

good job! the collision and detection should be really easy. just say that if the snake is beyond or equal to an x or y value then just fork it to a exit statement and say "u suk" lol. jk jk

Author:  LiquidDragon [ Sun May 16, 2004 4:56 pm ]
Post subject: 

LOL! yes that sounds like an excellent thing to say. But what's fork. I've never used that before Question

Author:  SuperGenius [ Sun May 16, 2004 4:59 pm ]
Post subject: 

fork is used to call a process. It works the same way as a procedure except it will run concurrently with the code below the fork statement. Be careful about process that use global variables though, because it can have problems.

Author:  white_dragon [ Sun May 16, 2004 5:00 pm ]
Post subject: 

just make a procedure then after ur done say

[code]
proc lose
*stuff u wanna put in here to say "u lose" n such*
end lose

fork lose
[/code]


BTW, who r u in WCI?

Author:  omni [ Sun May 16, 2004 5:05 pm ]
Post subject: 

its is used to call a process. Processes run alongside with your program

Author:  white_dragon [ Sun May 16, 2004 5:07 pm ]
Post subject: 

but there's two kinds.....well sorta..... there's procedures and processes.

their really different

btw, how do i put a code in cause it never works when i do it

Author:  SuperGenius [ Sun May 16, 2004 5:54 pm ]
Post subject: 

white_dragon wrote:
just make a procedure then after ur done say

code:

proc lose
*stuff u wanna put in here to say "u lose" n such*
end lose

fork lose




dont do this cause it's wrong. Procedures are called by a single word, which is the name of the procedure.

When a procedure is called the stack that called it will pause while the procedure is executing, and then when the procedure is finished the origional stack that called it will resume.

A process is called by saying "fork nameofprocess" When a stack calls a process it will keep going WHILE the process executes at the same time.

To accomplish this it would be best to use a procedure because if the game is over there is not much for the computer to do still, so this is what it should look like:
code:

proc lose
*stuff u wanna put in here to say "u lose" n such*
end lose
if loosecondition = true then
lose
end if
end lose

Author:  LiquidDragon [ Sun May 16, 2004 6:08 pm ]
Post subject: 

well all that forkin' fork stuff is forkin' confusing the fork outta me Thinking

Author:  LiquidDragon [ Mon May 17, 2004 2:53 pm ]
Post subject: 

Well i have run into another problem. I am trying to put my oranges onto a grid but it is not working.

this is the method im using to draw the orange on a grid.

code:

setscreen ("graphics:640;480")

var snake_length : int

snake_length := 4

proc orange_grid

    var orange_x_ar, orange_y_ar : array 1 .. 19 of int
    var count : int
    count := 0

    for pick_x : 139 .. 499 by 20
        count += 1
        orange_x_ar (count) := pick_x
    end for

    count := 0

    for pick_y : 59 .. 419 by 20
        count += 1
        orange_y_ar (count) := pick_y
    end for

end orange_grid

proc snake_up (var x, y : int)

    if whatdotcolor (x, y + 20) not= 7 then
        y += 20

        drawfillbox (x - 10, y, x + 10, y - 30, 0)
        drawfilloval (x, y, 10, 10, 12)
        drawfilloval (x - 4, y + 4, 2, 2, green)
        drawfilloval (x + 4, y + 4, 2, 2, green)
        drawfilloval (x, y - 20, 10, 10, 12) %Snake following
    end if

end snake_up

proc snake_down (var x, y : int)

    if whatdotcolor (x, y - 20) not= 7 then
        y -= 20

        drawfillbox (x - 10, y, x + 10, y + 30, 0)
        drawfilloval (x, y, 10, 10, 12)
        drawfilloval (x - 4, y - 4, 2, 2, green)
        drawfilloval (x + 4, y - 4, 2, 2, green)
        drawfilloval (x, y + 20, 10, 10, 12) %Snake following
    end if

end snake_down

proc snake_left (var x, y : int)

    if whatdotcolor (x - 20, y) not= 7 then
        x -= 20

        drawfillbox (x, y - 10, x + 30, y + 10, 0)
        drawfilloval (x, y, 10, 10, 12)
        drawfilloval (x - 4, y + 4, 2, 2, green)
        drawfilloval (x - 4, y - 4, 2, 2, green)
        drawfilloval (x + 20, y, 10, 10, 12) %Snake following
    end if

end snake_left

proc snake_right (var x, y : int)

    if whatdotcolor (x + 20, y) not= 7 then
        x += 20

        drawfillbox (x, y - 10, x - 30, y + 10, 0)
        drawfilloval (x, y, 10, 10, 12)
        drawfilloval (x + 4, y + 4, 2, 2, green)
        drawfilloval (x + 4, y - 4, 2, 2, green)
        drawfilloval (x - 20, y, 10, 10, 12) %Snake following
    end if

end snake_right


proc draw_orange (var x, y : int)

    var orange_x, orange_y : int
    var count : int

    orange_grid

    randint (orange_x, 1, 19)
    randint (orange_y, 1, 19)

    %draws orange
    drawfilloval (orange_x_ar (orange_x), orange_y_ar (orange_y), 10, 10, 41)


end draw_orange

proc orange_hit (var orange_x, orange_y, x, y : int)

    orange_grid

    if orange_x_ar (2) = x and orange_y_ar (2) = y then     %if snake gets orange
        put "SCORE"
        draw_orange (x, y)
    end if

end orange_hit


%boundaries
drawfillbox (115, 40, 128, 440, 7)         %left wall
drawfillbox (120, 430, 520, 440, 7)         %top wall
drawfillbox (511, 40, 520, 440, 7)         %right wall
drawfillbox (114, 35, 520, 48, 7)         %bottom wall

var x, y : int
var orange_x, orange_y : int
var key : string (1)
var move : string
var count : int
var erase_x, erase_y : array 1 .. 1000 of int

x := maxx div 2
y := maxy div 2

count := 0
move := "NONE"

draw_orange (x, y)

loop

    getch (key)

    loop

        count += 1

        erase_x (count) := x
        erase_y (count) := y

        if key = KEY_UP_ARROW then

            if move not= "DOWN" then
                snake_up (x, y)
                move := "UP"
            elsif move = "DOWN" then
                snake_down (x, y)
            end if

        elsif key = KEY_DOWN_ARROW then

            if move not= "UP" then
                snake_down (x, y)
                move := "DOWN"
            elsif move = "UP" then
                snake_up (x, y)
            end if

        elsif key = KEY_LEFT_ARROW then

            if move not= "RIGHT" then
                snake_left (x, y)
                move := "LEFT"
            elsif move = "RIGHT" then
                snake_right (x, y)
            end if

        elsif key = KEY_RIGHT_ARROW then

            if move not= "LEFT" then
                snake_right (x, y)
                move := "RIGHT"
            elsif move = "LEFT" then
                snake_left (x, y)
            end if

        end if

        delay (150)

        if count >= snake_length then
            drawfilloval (erase_x (count - snake_length + 1), erase_y (count - snake_length + 1), 10, 10, 0)
        end if

        orange_hit (orange_x, orange_y, x, y)

        exit when hasch

    end loop

end loop


EDIT: I fixed the orange grid drawing but now it has problems checking if it hit the orange. My code is really messed up right now so dont mind some of it but if you could plze help me fix it i will give you some bits Smile

Author:  SuperGenius [ Mon May 17, 2004 3:50 pm ]
Post subject: 

I'm a little confused as to exactly what you're asking, but anyways...

This was a point to consider during the making of my connect 4 game. The simplest way to keep track of the board was to have a 2d array. This effectively turns the board into a cartesian plane. So to take a set of coordinates you need to do something like this.(This is code from my connect 4)

code:

proc drawboard
    for h : 1 .. 8
        for c : 1 .. 8
            if board (h, c) not= " " then
                if board (h, c) = "RED" then
                    Draw.FillOval (130 + c * 60, 80 + h * 60, 25, 25, red)
                elsif board (h, c) = "GREEN" then
                    Draw.FillOval (130 + c * 60, 80 + h * 60, 25, 25, green)
                end if
            end if
        end for
    end for
end drawboard


You need to have a base number (in my case 130) which is the bottom of the grid minus 1/2 the size of the grid square. (if you are drawing circles because you need to give the x,y of the center) and then you add to the base the product of the x or y value on the cartesian plane times the width of each grid square.

Author:  LiquidDragon [ Mon May 17, 2004 5:27 pm ]
Post subject: 

So ar you trying to say that i should move my snake on an array instead of just drawing them?

What i was asking was to help me with drawing the orange and checking if the snake runs over it. In that code i devised a way to draw the orange but now its just a case of only drawing it once and checking if the snake runs over it.

EDIT: LOL!! looks like i solved my own problem again Embarassed Now i only need to check if the snake has run into itself. I'm also going to try to shorten my main program.

Author:  SuperGenius [ Mon May 17, 2004 7:26 pm ]
Post subject: 

oh dear. I seem to have gotten confused and posted in the wrong thread. Disregard that please. If any of you mods want to delete that post go ahead.

Author:  LiquidDragon [ Tue May 18, 2004 2:28 pm ]
Post subject: 

Ok so now the oranges are working but i can get it to check if my head hits the snake

EDIT: OK i got it to check if the snake hits itself. But i cant figure out anything else to add. Anyone got some ideas? So far im gonna have levels that have different speeds. I may add a wall in the middle for one level. But i still need a few more ideas.

Author:  LiquidDragon [ Thu May 20, 2004 2:46 pm ]
Post subject: 

Ok so things are coming along nicely but now im stuck again. Ok let me explain. I have that sword thing on the side and as your score increases the sword thing will fill up. When the score reaches 500 I want to sword to be completely coloured. Everytime the score increases i also want to colour to increment up the sword.

Author:  LiquidDragon [ Thu May 20, 2004 2:49 pm ]
Post subject: 

Heres the pictures

Author:  LiquidDragon [ Mon May 24, 2004 6:15 pm ]
Post subject: 

YAY i'm pretty much done my program now Dance I just need to add some losing screens and instructions and extra stuff

You can take a look if you like. I'll repost it when its completely finished. I'm just posting it now so you can have a quick peek before its completely finished. The pictures are posted above


: