Jeremy Read

XNA Smaller Snake

June 30, 2008 on 9:48 pm | In Uncategorized | 1 Comment | Jeremy Read

XNA Version of Snake Source Code Download

A bit bigger than some of the others, but it’s using textures unlike the original smaller snake.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;
 
namespace SnakeXNA
{
    static class Program
    {
        static void Main(string[] args)
        {
            using (SnakeXNA game = new SnakeXNA())
            {
                game.IsFixedTimeStep = true;
                game.TargetElapsedTime = new TimeSpan(500000);
                game.Run();
            }
        }
    }
 
    public class SnakeXNA : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;
 
        private static Random myRnd = new Random();
        private Point apple = new Point(myRnd.Next(64 - 1) * 10, myRnd.Next(48 - 1) * 10);
        private Point dir = new Point(0, 10);
        private LinkedList<Point> snake = new LinkedList<Point>(); //LinkedList doesn't have add...
        private Texture2D mySquare; //In XNA we need a texture to draw stuff with
        private Boolean isRunning = true;
 
        public SnakeXNA()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
        }
 
        protected override void Initialize()
        {
            snake.AddFirst(new Point(10, 10));
            base.Initialize();
        }
 
        protected override void LoadContent()
        {
            spriteBatch = new SpriteBatch(GraphicsDevice);
            mySquare = Content.Load<Texture2D>("GameThumbnail");  
        }
 
        protected override void Update(GameTime gameTime)
        {
            KeyboardState myState = Keyboard.GetState();
 
            if (myState.IsKeyDown(Keys.Left)) { dir = new Point(-10, 0); }
            if (myState.IsKeyDown(Keys.Right)) { dir = new Point(10, 0); }
            if (myState.IsKeyDown(Keys.Up)) { dir = new Point(0, -10); }
            if (myState.IsKeyDown(Keys.Down)) { dir = new Point(0, 10); }
 
            if (isRunning)
            {
                snake.AddFirst(new Point(snake.First.Value.X + dir.X, snake.First.Value.Y + dir.Y));
                snake.RemoveLast();
            }
 
            base.Update(gameTime);
        }
 
        protected override void Draw(GameTime gameTime)
        {
            graphics.GraphicsDevice.Clear(Color.CornflowerBlue);
 
            spriteBatch.Begin(SpriteBlendMode.AlphaBlend);
            spriteBatch.Draw(mySquare, new Rectangle(apple.X + 2, apple.Y + 2, 5, 5), Color.Green); //Draw apple.
 
            int i = 0;
            foreach (Point cur in snake)  //Draw snake and check self collision
            {
                spriteBatch.Draw(mySquare, new Rectangle(cur.X , cur.Y , 10, 10), Color.White);
                if (i != 0 && snake.First.Value.X == cur.X && snake.First.Value.Y == cur.Y) { isRunning = false ; }
                i++;
            }
 
            if (snake.First.Value.X == apple.X && snake.First.Value.Y == apple.Y) //Collision apple
            {
                apple = new Point((myRnd.Next(64 - 1)) * 10, (myRnd.Next(48 - 1)) * 10);
                snake.AddLast(snake.Last.Value);
            }
 
            spriteBatch.End();
            base.Draw(gameTime);
        }
    }
}
Jeremy Read

Smaller snake in C#

June 29, 2008 on 4:55 pm | In Uncategorized | No Comments | Jeremy Read

Now with full initialization. Tomorrow I should have XNA up as well. Then I’ll get to work on a simple tower defense game. Smaller Snake in C#

Executable Download

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
 
namespace SnakeCSharp
{
	public partial class SnakeCSharpWindow : Form
	{
		private Timer t = new Timer();
		private static Random myRnd = new Random();
		private Point apple = new Point(myRnd.Next(64-1) * 10, myRnd.Next(48-1) * 10);
		private Point dir = new Point(0, 10);
		private LinkedList<Point> snake = new LinkedList<Point>(); //LinkedList doesn't have add...
 
		public SnakeCSharpWindow()
		{
			this.ClientSize = new System.Drawing.Size(640, 480);
			this.FormBorderStyle = FormBorderStyle.FixedSingle;
			this.Name = "SnakeCSharpWindow";
			this.Text = "SnakeCSharp";
			this.Paint += new PaintEventHandler(SnakeCSharpWindow_Paint);
			this.KeyDown += new KeyEventHandler(SnakeCSharpWindow_KeyDown);
			t.Tick += new EventHandler(t_Tick);
			t.Start();
			snake.AddFirst(new Point(10,10));
		}
 
		void SnakeCSharpWindow_KeyDown(object sender, KeyEventArgs e) //Change direction
		{
			if (e.KeyCode == Keys.Left) {dir = new Point (-10,0 );}
			if (e.KeyCode == Keys.Right) {dir = new Point(10, 0);}
			if (e.KeyCode == Keys.Up) {dir = new Point(0, -10);}
			if (e.KeyCode == Keys.Down) {dir = new Point(0, 10);}
		}
 
		void SnakeCSharpWindow_Paint(object sender, PaintEventArgs e)
		{
			e.Graphics.FillRectangle(Brushes.Green, apple.X  + 2, apple.Y + 2, 5, 5);
 
			int i = 0;
			foreach (Point cur in snake)  //Draw snake and check self collision
			{
				e.Graphics.FillRectangle(Brushes.Black, cur.X, cur.Y, 10, 10);
				if (i != 0 && snake.First.Value.X == cur.X && snake.First.Value.Y == cur.Y ) { t.Stop(); }
				i++;
			}
 
			if (snake.First.Value.X == apple.X && snake.First.Value.Y == apple.Y) //Collision apple
			{
				apple = new Point((myRnd.Next(64-1)) * 10, (myRnd.Next(48-1)) * 10);
				snake.AddLast(snake.Last.Value);
			}
 
		}
		void t_Tick(object sender, EventArgs e) //Move Snake
		{
			snake.AddFirst(new Point(snake.First.Value.X + dir.X, snake.First.Value.Y + dir.Y));
			snake.RemoveLast();
			this.Refresh();
		}
	}
}
DarkSentinel

Primers for PTQ: Berlin

June 23, 2008 on 10:29 am | In Magic | No Comments | DarkSentinel

Preparing for PTQ: Berlin
As stated elsewhere, I can’t actually make it to the Wellington PTQ, and the Auckland one will include Eventide so is entirely a different ballgame. With that in mind, I thought I’d share some more fruits of my deck design, and testing, of the last few weeks. I must mention that the deck design may be a bit more radical than usual (:o) since I’ve been consciously avoiding a tribal theme to the newer decks. Also my playtesting has been limited to around 10 games per deck, due to time contrainsts posed by impending (and current) exams. And since I can’t concentrate on study at the moment, you get this literary masterpiece instead. I must mention that my phone and internet went out around midday today (sunday), and according to Telecom this fault affects around 200 people in my area and will be resolved by around 1900 hours on Tuesday (55 hours later). I’m uncertain what sort of fault takes two working days to fix, but later on Telecom sent me the following helpful text message: “If you service is not restored by: 19:00pm on 24.3.06 call 120.”. That’s right, NZ’s biggest telecommunications provider thinks it’s currently March two years ago, so I probably shouldn’t be surprised that their service is a touch on the unsatisfactory side. I tend to upload this tomorrow at Uni, so if you’re reading this that is probably what happened; additionally I don’t have a chance to check decklists online, so am working from memory, and personal notes.
Continue reading Primers for PTQ: Berlin…

arbscht

Even Smaller Snake

June 23, 2008 on 8:57 am | In Uncategorized | 5 Comments | arbscht

In 35 lines. (It had to be done.)

Here’s a take on Jeremy’s Snake, implemented in Clojure (a Lisp for the JVM). As you can see, I’m still using the same library classes. Only the language is different.

A major difference is that this is the whole application code, including incantations and setup. Excerpting the Snake-specific bits would make it shorter — maybe under 30 lines even.

Still, it is a little messy for the sake of brevity. With a more liberal style, it could be a neat 50-100 line Snake.

Update [Tue Dec 30 12:58:04 NZDT 2008]: The original code in this post was written to an old version of Clojure (Jun 2008), which has since been replaced by newer versions that introduce breaking changes. An updated snippet follows, which is known to work with Clojure SVN rev 1185 (Dec 2008). Thanks to Chouser and Stephen C. Gilardi for additional idiomatic updates, reducing line count.

These versions of the program are intended to be abnormally terse. For an expanded and readable presentation, check out Mark Volkmann’s edition, which is more instructive to humans.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
(import '(java.awt Color) '(javax.swing JPanel JFrame Timer)
         '(java.awt.event KeyEvent ActionListener KeyListener))
 
(defn gen-apple [_] [(rand-int 750) (rand-int 550)])
(defn move [{:keys [body dir] :as snake} & grow]
   (assoc snake :body (cons (vec (map #(+ (dir %) ((first body) %)) [0  
1]))
                            (if grow body (butlast body)))))
(defn turn [snake newdir] (if newdir (assoc snake :dir newdir) snake))
(defn collision? [{[b] :body} a]
   (every? #(<= (- (a %) 10) (b %) (+ 10 (a %))) [0 1]))
(defn paint [g p c] (.setColor g c) (.fillRect g (p 0) (p 1) 10 10))
 
(def dirs {KeyEvent/VK_LEFT [-10 0] KeyEvent/VK_RIGHT [10 0]
            KeyEvent/VK_UP   [0 -10] KeyEvent/VK_DOWN  [0 10]})
(def apple (atom (gen-apple nil)))
(def snake (atom {:body (list [10 10]) :dir [10 0]}))
(def colors {:apple (Color. 210 50 90) :snake (Color. 15 160 70)})
(def panel (proxy [JPanel ActionListener KeyListener] []
              (paintComponent [g] (proxy-super paintComponent g)
                              (paint g @apple (colors :apple))
                              (doseq [p (:body @snake)]
                                (paint g p (colors :snake))))
              (actionPerformed [e] (if (collision? @snake @apple)
                                     (do (swap! apple gen-apple)
                                         (swap! snake move :grow))
                                     (swap! snake move))
                               (.repaint this))
              (keyPressed [e] (swap! snake turn (dirs (.getKeyCode e))))
              (keyReleased [e])
              (keyTyped [e])))
 
(doto panel (.setFocusable true)(.addKeyListener panel))
(doto (JFrame. "Snake")(.add panel)(.setSize 800 600)(.setVisible true))
(.start (Timer. 75 panel))
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
;(import '(java.awt.event KeyEvent ActionListener KeyListener)
;        '(javax.swing JPanel JFrame Timer))
 
;(defn gen-apple [] {:x (int (* 790 (. Math (random)))) :y (int (* 590 (. Math (random))))})
 
;(def snake (ref {:body (list {:x 10 :y 10}) :dir {:x 10 :y 0}}))
;(def apple (ref (gen-apple)))
;(def dirs {(. KeyEvent VK_LEFT) {:x -10 :y 0} (. KeyEvent VK_RIGHT) {:x 10 :y 0}
;           (. KeyEvent VK_UP)   {:x 0 :y -10} (. KeyEvent VK_DOWN)  {:x 0 :y 10}})
 
;(defn move [{body :body dir :dir :as snake} & opts]
;  (merge snake {:body (cons {:x (+ (:x dir) (:x (first body)))
;                             :y (+ (:y dir) (:y (first body)))}
;                            (if (:grow (apply hash-map opts)) body (butlast body)))}))
 
;(defn turn [snake newdir] (if newdir {:body (:body snake) :dir newdir} snake))
 
;(defn collision? [{[b & bs] :body} a]
;  (and (>= (+ 10 (:x b)) (:x a)) (<= (:x b) (+ 10 (:x a)))
;       (>= (+ 10 (:y b)) (:y a)) (<= (:y b) (+ 10 (:y a)))))
 
;(defn run-snake []
;  (let [panel (proxy [JPanel ActionListener KeyListener] []
;                (paintComponent [g] (proxy-super paintComponent g)
;                                    (. g (fillRect (:x @apple) (:y @apple) 10 10))
;                                    (doseq p (:body @snake) (. g (fillRect (:x p) (:y p) 10 10)))
;                                    (if (collision? @snake @apple)
;                                      (dosync (ref-set apple (gen-apple))
;                                              (alter snake move :grow true))))
;                (actionPerformed [e] (dosync (alter snake move))
;                                     (. this (repaint)))
;                (keyPressed [e] (dosync (alter snake turn (get dirs (. e (getKeyCode)))))))]
;    (doto panel (setFocusable true) (addKeyListener panel))
;    (doto (new JFrame "Snake") (add panel) (setSize 800 600) (setVisible true))
;    (. (new Timer 75 panel) (start))))

Edit: fixed per cgrand’s comment.

Jeremy Read

Smaller snake

June 22, 2008 on 4:51 pm | In Uncategorized | 2 Comments | Jeremy Read

Since we all love CompSci 101 so much, also as I’m testing out the source code highlighting plugin I present ’smaller snake’. You could write Snake a little smaller by storing head and apple in the same array as each other, or better yet with the snake. But I think this is just about as small as you can make it in java and still be ‘readable’. Apple probably shouldn’t be from fixed values or should be based on the container size, but I’m too lazy to fix it now.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;
 
public class SnakeJPanel extends JPanel implements ActionListener, KeyListener, MouseListener  {
 
	private javax.swing.Timer t = new javax.swing.Timer(75,this);
	private LinkedList<Point> snake = new LinkedList(); 
	private Point apple = new Point( (int)(Math.random() * 45) * 10, (int)(Math.random() * 45) * 10);
	private Point dir = new Point(0,10);
 
	public SnakeJPanel() {
		t.start(); //To make stuff work.
		addMouseListener(this); 
		addKeyListener(this);
		snake.add(new Point(10,10));	
	}
 
	public void paintComponent(Graphics g) {
		super.paintComponent(g);
 
		g.fill3DRect(apple.x + 2,apple.y + 2, 5,5,true)	; //Draw apple
		for(int i = 0; i < snake.size(); i++){ //Draw snake and check self collision
			g.fill3DRect( snake.get(i).x,  snake.get(i).y , 10 , 10, true); 
			if( i != 0 && snake.get(i).x == snake.getFirst().x && snake.get(i).y == snake.getFirst().y){ t.stop(); }	//Check collision.	
		}
 
		if(snake.getFirst().x == apple.x && snake.getFirst().y == apple.y){ //Collision apple
			apple = new Point((int)(Math.random() * 45) * 10,(int)(Math.random() * 45) * 10);
			snake.add(snake.getLast());
		}
	}
 
	public void actionPerformed(ActionEvent e){ //Move snake
		snake.addFirst(new Point(snake.getFirst().x + dir.x, snake.getFirst().y + dir.y));
		snake.removeLast();
		repaint();
	}
	public void keyPressed(KeyEvent e){ //Change direction
		if(e.getKeyCode() == KeyEvent.VK_LEFT){dir = new Point(-10,0);}
		if(e.getKeyCode() == KeyEvent.VK_RIGHT){dir = new Point(10,0);}
		if(e.getKeyCode() == KeyEvent.VK_UP){dir = new Point(0,-10);}
		if(e.getKeyCode() == KeyEvent.VK_DOWN){dir = new Point(0,10);}
	}
 
	public void mousePressed(MouseEvent e){ //Java Hack
        super.requestFocus();
        repaint();
    }
    public void mouseClicked(MouseEvent e){}
    public void mouseEntered(MouseEvent e){}
    public void mouseExited(MouseEvent e){}
    public void mouseReleased(MouseEvent e){} 	
    public void keyReleased(KeyEvent e){} 
    public void keyTyped(KeyEvent e){}
}
Jeremy Read

Ramble ramble rambo

June 21, 2008 on 6:34 pm | In Uncategorized | No Comments | Jeremy Read

It’s that time again. There’s not much you can to do avoid it, since I hold the trump card of Admin. Mostly I don’t post as I don’t think anyone really gives a shit anyway. So I just work away in the background fixing what breaks every couple of weeks. But I’m going to take a break from playing Urban Terror (I blame Abhishek for introducing me) and utilizing my subscription to Marvel Digital, both of which I’m quite glad for really as they help break up the monotony of trying to work out what to do next.

Thus I’m going to post a fraction of my thoughts on the past week.

The Tiramisu and Creme Brulee chocolate from cadbury, don’t taste anything like what they’re supposed to. They’re okay though, as long as you forget what they’re meant to be.

Cadbury Old Gold Liquer Flavoured Selection.

Tastes like cooking chocolate. The Irish creme centers are pretty bland

What’s up with “Intensity” though?

Their entire range is rated 3/5 cocoa beans for intensity! Why would you rate your own product like that?

On the chocolate note I went down the local liquor store last night and purchased another two bottles of Creme da Cacao. One bottle of De Kuyper dark and one of Continental white.

De Kuyper is about $25 to the Continental at $20, it’s less syrupy with a more complex taste but unfortunately that complex taste also tastes kind of like dirt. Drinking it straight the De Kuyper is probably better, but if you were mixing it with say milk then I’d save my money and get the Continental if possible.

Though I possibly shouldn’t do that since apparently I live in Manurewa now (who’s border is soon to reach the North Shore if TV3 has it’s way) and drinking alcohol will thus fuel me to commit further murders.

Maybe the only place safe is to go further south. Last Thursday I went out with some friends to the Sahara Tent for dinner in Papakura, (brand loyalty most likely, if you haven’t been it’s worth going at least once [get the Chef's Special, trust me]) and I believe that we all successfully went without being stabbed, shot etc.

Though whether in the greater scheme of things this is important who knows, with the world ending in half a month. Which is fitting in a way since it’s like three days after I’ll get my laptop, on the plus side I won’t have to worry about the interest payments on my credit card.

Which reminds me, how are you meant to buy a house now?

Suppose you had a reasonably well paying job at 80K/year before tax.

Before tax: $80000/year
Tax: $22470/year

After $57530/year

The maximum you ever borrow is such that the interest payments are at most 30% of your after tax income.

$57530* 30% = $17259/year

At the moment variable rate is about 11% per annum.

Loan*11% = 17529

Loan*0.11 = 17529

Loan = 17529/0.11
=$159354.54
= ~$160,000
That’s not much, you’re going to have to save a pretty hefty deposit to afford to live inside Auckland. No wonder so many people are flatting.

Well not that it’ll matter next month anyway :P

Link of the day: Desktopography.net

arbscht

Multitasking

June 20, 2008 on 9:44 pm | In Uncategorized | No Comments | arbscht

So I came upon this article on the Myth of Multitasking. I think its premise is something like: multitasking is really impossible, perhaps dangerous to attempt, and detrimental to learning. Or something like that. You see, I don’t know for sure because I couldn’t actually bring myself to read the lengthy piece.

In fact, when I got past the first paragraph, I couldn’t help but interrupt my reading to wryly note how funny it was that I just did that. And then, in the following hour or two, I skimmed a few other websites and blog posts, played a game, wrote some code, updated some software, ate cake, chatted a bit, and wrote this post.

BRB.

Atomix

Film Strip #4 - Hobby 26

June 19, 2008 on 10:46 am | In Uncategorized | No Comments | Atomix

Atomix

Film Strip #3 - Banana

June 17, 2008 on 5:18 pm | In Pictures | No Comments | Atomix

Next Page »

Powered by WordPress with Pool theme design by Borja Fernandez.
Entries and comments feeds. Valid XHTML and CSS. ^Top^