Monday, April 25, 2011

First real program

Today I was looking back over the first real program I ever wrote. It was for my Casio fx-9750G plus graphing calculator which I had in college. The calculator had a basic derived language that was quite powerful, if at times difficult to use due to having to navigate the menus to insert keywords. I had played around a bit with the programs given in the book, and a few games that I had found on the net, but I wanted to make something a bit more interesting, something you could actually play with a friend (and I was thinking an AI, but never got round to that).

I had played a game where you had to set the power, and the aim was to hit a target. However it was quite simplistic, and you only got one shot before it changed the position, which was a bit frustrating. I took the idea, and the basic formula for the projectile from that game, and made ARTILERY (only one L as the name of a program could be a max of 8 chars). It's basically a simple tank game, with three weapons (of successively smaller damage areas, but higher damage), with alternating turns, and wind. Source code follows. Note that the comments were added by me when I typed it up (previously I wrote it out on a piece of refill). I was actually surprised how much of the mechanics I remembered, or could figure out without too much difficulty. Feel free to do the laborious task of typing this out into your calculator if you have one and want to play.

# This is a simple artillery game
# 1502 bytes
# -> means the assignment operator, →
# => means the single line then operator, ⇒
# Try holding the keys down rather than just pressing them when playing

ClrText                                                    # [SHIFT][PRGM][F6][F1][F1] for ClrText
"    --ARTILLERY--"
" "
" "
"  0=HELP 1~9=START"?->A
If A=0
Then ClrText
"<-/-> = CHANGE WEAPONUP/DOWN = POWER+5/-5 F5/F6 = POWER-1/+1"       # [F6][F5] for /
"+/- = ANGLE+5/-5"
"EXE = FIRE"◢
IfEnd
ViewWindow 0,80,0,0,30,0,0,4,.1
AxesOff                                                    # [SHIFT][MENU][F4][F2] for AxesOff
Deg                                                        # Sets angles to degrees, [SHIFT][MENU][F1][F1] for 'Deg'
ᴇ2->C~D                                                    # ᴇ=EXP, C=p1 hp, D=p2 hp
Int 51Ran#-25->W                                           # W=wind
0->Z                                                       # Z=0/1 => plyr 1/2's turn
28Ran#+7->E                                                # E=left player's position
28Ran#+45->F                                               # F=right player's position
F-1.5->P
E+1.5->O
Lbl 1                                                      # Lbl 1 = start a player's turn
Cls
F-Line E,0,E+3,2                                           # [SHIFT][F4][F6][F2][F2] for F-Line
F-Line F,0,F-3,2
F-Line E+3,0,E+1.5,1
F-Line F-3,0,F-1.5,1
O->Q
P->O
Q->P
Text 1,1,"WIND="                                           # [SHIFT][F4][F6][F6][F2] for Text 
Text 8,1,"DIR="
Text 1,78,"POWER="
Text 8,78,"ANGLE="
Text 1,40,"WEAPON="
Text 15,1,"PLYR 1="
Text 15,78,"PLYR 2="
Text 15,43,"TIME="
15->T                                                      # T=time
0->N                                                       # N=0 on the first iteration of main loop
45->A                                                      # A=angle
30->V                                                      # V=velocity (power)
1->G                                                       # G=1/2/3 shrapnel/explosive/bomb
If Z=0
Then C->S
D->C
S->D
1->Z
Text 22,10,"^"
1->R                                                       # R=direction multiplier
Else 0->Z
Text 22,110,"^"
-1->R
IfEnd
Text 15,30,C                                               # Show each player's hp
Text 15,107,D
If Z=0
Then D->S
C->D
S->C
IfEnd
Lbl 2                                                      # Lbl 2 = main game loop
Int 51Ran#-25->B                                           # Set the wind
B>W=>W+1->W
BW-1->W
Text 1,25,"   "                                            # 3 spaces to cover the previous wind
Text 1,25,W
W>0=>Text 8,24,"->"                                        # Set the wind direction arrow
W<0=>Text 8,24,"<-"
Text 15,65,"  "                                            # 2 spaces to cover the previous time
Text 15,65,T
T=0=>Goto 4                                                # Time's up
T-1->T
Getkey->K                                                  # Read keypad input [SHIFT][VARS][F6][F4][F2] for Getkey
N=0=>Goto 3                                                # Process keypress on first iteration to draw everything, skip later
K=0=>Goto 2                                                # Restart the event loop if no keypress
Lbl 3                                                      # Lbl 3 = process key press
N=0=>1->N
K=27=>G≠3=>G+1->G                                          # Pressed -> to get next weapon
K=38=>G≠1=>G-1->G                                          # Pressed <- to get previous weapon
G=1=>Text 8,40,"SHRAPNEL "                                 # Spaces for padding to ensure old text is covered
G=2=>Text 8,40,"EXPLOSIVE"
G=3=>Text 8,40,"BOMB     "
K=28=>V+5->V                                               # Pressed up to increase velocity by 5
K=29=>V+1->V                                               # Pressed F6 to increase velocity by 1
K=37=>V>0=>V-5->V                                          # Pressed down to decrease velocity by 5
K=39=>V>0=>V-1->V                                          # Pressed F5 to decrease velocity by 1
Text 1,106,V                                               # Write the current velocity on screen
K=42=>A+5->A                                               # Pressed + so increase angle by 5
K=32=>A>0=>A-5->A                                          # Pressed - so decrease angle by 5
Text 8,106,A                                               # Write the current angle on screen
If K=31                                                    # Pressed EXE so fire!
Then Graph(X,Y)=(R(.5V+5+.35RWT)cos A✕T+P,(.5V+5)sin A✕T-4.9T²       # Draws the shot, [SHIFT][F4][F5][F3] for 'Graph(X,Y)=('
(.5V+5)sin A÷4.9->T                                        # T=Time before projectile hit
R(.5V+5+.35RWT)cos A✕T+P->L                                # L=X coord (location) projectile hit
If G=1                                                     # Draw the blast (shrapnel)
Then For -5->Y To 5 Step 10
F-Line L,0,L+2Y,1
F-Line L,0,L+4⌟3Y,1.5
F-Line L,0,L+.5Y,2
Next
L≤O+10=>L≥O-10=>D-30+Int (2Abs (L-O))->D                   # Deal damage, based on distance from blast
IfEnd
If G=2                                                     # explosive
Then For -1->Y To 1 Step 2
F-Line L,0,L-5Y,.75
F-Line L,0,L-3Y,1.5
F-Line L,0,L-1.5Y,2
Next
L≤O+5=>L≥O-5=>D-50+Int (6Abs (L-O))->D
IfEnd
If G=3                                                     # bomb
Then F-Line L-2.5,0,L+2.5,0
F-Line L-1.5,.5,L+1.5,.5
F-Line L-1,1,L+1,1
L≤O+2.5=>L≥O-2.5=>D-80+Int (16Abs (L-O))->D
IfEnd
Text 30,49,"BOOM!"
If D≤0                                                     # hp≤0, so game over
Then Text 45,33,"PLAYER 2 WINS!"
If Z=0
Then Text 15,30,"  "                                       # 2 spaces
Text 15,30,D                                               # Print out final hp
Else Text 45,61,1                                          # Overwrite the 2 with a 1 in "PLAYER 2 WINS!"
Text 15,107,"  "                                           # 2 spaces
Text 15,107,D
IfEnd
Stop                                                       # [SHIFT][VARS][F2][F4] for Stop
IfEnd
Goto A
IfEnd
Goto 2
Lbl 4
Text 30,42,"TIME UP!"
Lbl A
Text 40,42,"PRESS EXE"◢
Goto 1

Saturday, April 23, 2011

Decoding email attachment

Yesterday, I received an email with an attachment (in gmail), but for some reason it showed the attachment was there, but no download link (though it appears now). Wanting to view the attachment, I did some brute force hackery. In gmail you can hit the link "show original" which shows the original text of the email, including the attachments. So I saved this as a text file, deleted everything but the base64 encoded data (i.e the attachment). Then I used the base64 command line tool (imaginatively called base64), that everyone should have installed already, to decode this data, and to just a little surprise, it all worked. I was quite pleased with that. I also just had a look at the wikipedia page for base64 encoding to see how it works. You should too, it's quite simple, but effective.

Monday, April 18, 2011

Underoath

I sometimes forget how much I love listening to Underoath. They're such a great band, particularly their last three albums (Define the Great Line, Lost In The Sound of Separation, and Ø (Disambiguation)). Sometimes it can be a bit heavy, and I'm not in the mood for it, but so often it just fits perfectly. Good music, good lyrics (even if they can be hard to interpret at times).

I can just sit and listen for ages. Or I sit and listen with the lyrics in front of me (Ctrl+T in banshee), and finally learn what they're actually saying. They usually speak of the troubles of life, particularly life as a Christian, in a world where it can be hard.

For instance, the song I'm listening to now, A Fault Line, A Fault of Mine has the verse:

I was lying when I said, I was looking up
I was too scared to show what I am
Bear with me, bear with me, this is all I have left
This might be more than a simple conversation

Which is exactly how I feel at times. I find it encouraging, and it's really helped me through some times when I haven't been feeling myself. Give them a listen, you might enjoy it (or get a headache).

Saturday, April 16, 2011

gnome terminal unlimited scrollback

A recent, and very handy feature that came out in gnome terminal (my currently preferred terminal program, basically because I use gnome), was unlimited scrollback. I thought I'd try it for a while, to see if it would have any negative effects on performance (particularly memory use), as it'd be a useful thing to have, as there have been a number of times I've lost output that I would've liked to have kept off the top of the buffer.

The first thing I did was to fill the terminal with a whole lot of output, to see what would happen. My preferred way of doing this was simply $ base64 < /dev/urandom, which avoids the problem of strange things happening due to the non-printable characters. After running that for a while, I didn't notice the memory usage increasing, but also couldn't find any new large files in my home directory, or /tmp. Which left me a little confused.

They're probably using some kind of fancy compression was my next thought (despite random data being impossible to compress). So I changed my command to run as $ base64 < /dev/urandom | tee tmp to make a temporary file of the output as well as spitting it out. Compressing that with xz, bzip2 and gz all shrunk it to about 70% of the file size (remember, it's base64 encoded random data, so we can actually compress it). As a sidenote, the compressed base64 random data was about 5% larger than just the pure random data - which itself can't be compressed. So this led me to think that they couldn't be compressing it all away to virtually nothing, it's got to be somewhere. (Meanwhile, I left the command running, filling up my terminal).

My next port of call was to have a look at the source code. So I git cloned the gnome-terminal repo, which it turns out uses another gnome library, vte, which I also cloned. I could find where the setting was defined, and it turns out "unlimited" just means there are a max G_MAXLONG in the buffer (which is effectively infinite). I also found mention in a comment that it was saving it to disk, but I couldn't find where it was saving the data.

But then I saw the light. I could just look at what files gnome-terminal had open, so lsof to the rescue. Then I found it was being sneaky, it had a number of files called /tmp/vteXYZ1tv open, but it had already deleted them. Thus you can't see them when browsing, and they will be removed when the program closes. This makes sense, it means that when the process is closed, it doesn't matter how (at least I think), the space of the files can be reclaimed, i.e. we won't get leftover files on a program crash, or a kill -9. They can be restored though, my way (there are probably others), was to do a ls -l /proc/<gnome-terminal pid>/fd to see what they point to. Then you can cat these to make a new file. These are just a verbatim copy of the terminal output. No compression. No nothing. As it turns out, one of my terminal history's was almost 900 MB! But that was only after random data being spat out very quickly for quite a while, unlikely to happen in ordinary usage. For the foreseeable future though, I think I'll keep this option checked, as I can live with a bit of disk usage for the handiness.

Monday, December 13, 2010

Biscuit denser than a neutron star

Over lunch, a couple of friends and I happened to be talking about biscuits, among other things. As we all know, a biscuit tends to absorb water from its surroundings, as it is generally drier than them. Now if we place a biscuit next to the ocean, it would slowly absorb all the water out of the worlds oceans, while maintaining the same volume (yes, we knew that this is completely impossible).

Now lets throw some numbers in. According to wolfram alpha, the volume of the world's oceans is 1.3 x 10^21 L, for an approximate mass of 1.3 x 10^21 kg. Biscuits vary in size, but we took ours to be a cylinder of radius 3 cm, and height 0.5 cm, for an approximate volume of pi x 3^2 x .5 = 14 cm^3 = 1.4 x 10^-5 m^3. Thus the density of the biscuit (as the mass of the biscuit is negligible compared to the water) is about 10^26 kg m^-3. For a comparison, this is much denser than the density of a neutron star, which is typically 8 x 10^16 to 2 x 10^18 kg m^-3 (this agrees with the value of 2 x 10^17 that I calculated in an assignment not so long ago), which, according to wikipedia is "approximately equivalent to the mass of the entire human population compressed to the size of a sugar cube."

So, there you have it. What's denser than a neutron star? A biscuit (containing all the world's oceans).

Thursday, July 8, 2010

Sound arguments require basic logic

Sound arguments require basic logic. Sounds obvious, right? But it seems that some people just don't understand this. Or maybe they understand basic logic incorrectly. Anywho, when someone structures an argument in such a way that it doesn't actually prove the point they were trying to argue, I find it mildly amusing. It happens often too. I'm going to go on to describe one example of this that I encountered recently.

So, a little while ago, I went to a talk entitled, "Is religion inherently violent?". I don't care where you stand on this issue, it is just to illustrate my point. The speaker went on to demonstrate that violence exists outside of religion with a variety of examples, particularly from the 20th century. She also put forward one way that violence would develop in any group of people, religious or otherwise.

You see what she did? The issue itself wasn't addressed at all. By showing that violence exists outside of religion, you're not saying anything about whether or not religion is inherently violent. What she wanted to prove was that religion does not imply violence, but what was shown was that violence can result outside religion.

On the other hand, if you couldn't show that there was violence outside of religion, and there existed some violence, that would be a proof that all violence comes from religion. Not a proof that religion is inherently violent as there could still be some religions that don't cause violence. I can see how people can get confused, but it's not too hard really, if you just think about it.

Lastly, I'm not saying the talk was bad, she did bring forward an interesting point. I'm just saying that she didn't prove the argument the talk was supposed to be based on.

Wednesday, June 30, 2010

A proof that there is no onto homomorphism from S_5 to S_4

Warning: contains maths, algebra even.

This is probably one of the most satisfying proofs that I've ever come up with (or at least remember coming up with). This is partly due to the fact it is non trivial, and partly due to the amount of time it took to come up with it.

Anyway, here's how it goes:

Suppose there is an onto homomorphism \(\varphi\) from \(S_5\) to \(S_4\).

By the first isomorphism theorem, \(S_4 \cong \, ^{S_5}\!/_{\mathrm{ker} \varphi}\), so \(\left| \mathrm{ker} \varphi \right| = \frac{\left| S_5 \right|}{\left| S_4 \right|} = 5\).

As this is prime, \(\mathrm{ker} \varphi\) is cyclic.

Let \(x\) be an element that generates \(\mathrm{ker} \varphi\). \(x\) is an even permutation as \(x^5 = 1_{\mathrm{ker} \varphi}\), so \(\mathrm{sgn}(x)^5 = 1\) and \(\mathrm{sgn}(x) = 1\).

Therefore all elements of \(\mathrm{ker} \varphi\) are even, so \(\mathrm{ker} \varphi \subseteq A_5\), the alternating group.

But \(\mathrm{ker} \varphi \lhd S_5\), so \(\mathrm{ker} \varphi \lhd A_5\), which is a contradiction as \(A_5\) is simple.

So there does not exist such a homomorphism.

Sure, I assumed that \(A_5\) was simple, but we all know that, right?