Java 4k competition 2011
Finally the time a year when you are encouraged to write really dirty code, Java 4k competition! Well, maybe not dirty but certainly ugly.
This year i forgot to exclude the manifest before i started with the size optimizations. I felt like a child on christmas when i discovered it! Good times :) Anyway, my game is a classic puzzle game where you control a rolling cube. The objective is to clear all colored bricks on the playfield by rolling over the bricks with the a side of the cube which have the same color as the brick. The game can be found on the Java 4k site and I encourage you to try all submitted games, some of them are really good.
Because Riven's excellent Compile 'n Shrink service seems to be down, probably due to the hacking of java-gaming.org, I'll post my own compression scripts here.
This is the script I use for this tedious task:
The Java 4K competition is a game programmer competition. The goal of the competition is to create the best game possible in Java. But what's the catch? Well, it wouldn't be fun if there wasn't any catch! There are limitations, and these limitations are: The maximum allowed size of a game is only 4K
This year i forgot to exclude the manifest before i started with the size optimizations. I felt like a child on christmas when i discovered it! Good times :) Anyway, my game is a classic puzzle game where you control a rolling cube. The objective is to clear all colored bricks on the playfield by rolling over the bricks with the a side of the cube which have the same color as the brick. The game can be found on the Java 4k site and I encourage you to try all submitted games, some of them are really good.
Because Riven's excellent Compile 'n Shrink service seems to be down, probably due to the hacking of java-gaming.org, I'll post my own compression scripts here.
This is the script I use for this tedious task:
#!/bin/bash if [ $# -ne 1 ] then echo "Usage: `basename $0`For even smaller files, replace the kzip command with a script that runs kzip 10-100 times and takes the smallest resulting file. You will also need pjt33's Zip2Gzip converter to convert the KZip files to GZip:" exit 65 fi function printSize() { SIZE=$(ls -l $1 | awk '//{print $5}') printf "+ %-15s %s bytes [%d]\\n" $1 ${SIZE} $((SIZE-4096)) } BIN=bin LOG=../size.log PRO_FLAGS="-libraryjars /lib/rt.jar -basedirectory ." CLASS=$1.class JAR=$1.jar PACK=$1.pack.gz PRO=$1.pro.jar PRO_PACK=$1.pro.pack.gz PRO_PACK_RAW=$1.pro.pack PRO_PACK_7ZIP=$1.pro.pack.7.gz PRO_PACK_K=$1.pro.pack.kzip PRO_PACK_K_GZ=$1.pro.pack.k.gz pushd . cd $BIN echo #echo Generating manifest file #echo -e Main-Class: $1\\n > $1.manifest echo Running jar on $CLASS jar cfM $JAR $CLASS echo Running Proguard on $JAR proguard $PRO_FLAGS -injars $JAR -outjars $PRO -keep public class $1 echo Running pack200 on $JAR pack200 -G $PACK $JAR echo Running pack200 on $PRO pack200 -G $PRO_PACK $PRO pack200 --no-gzip $PRO_PACK_RAW $PRO echo Compressing $PRO_PACK_RAW with 7zip 7z a -mx=9 -tgzip $PRO_PACK_7ZIP $PRO_PACK_RAW > /dev/null echo Compressing $PRO_PACK_RAW with Kzip kzip /q /y /s0 /rn /b64 $PRO_PACK_K $PRO_PACK_RAW zip2gzip $PRO_PACK_K $PRO_PACK_K_GZ echo echo File size summary: printSize $CLASS printSize $JAR printSize $PRO printSize $PACK printSize $PRO_PACK printSize $PRO_PACK_7ZIP printSize $PRO_PACK_K_GZ echo # Write to the log file echo "----------------------------------" >> $LOG date +"%Y-%m-%d %H:%M:%S" >> $LOG echo "----------------------------------" >> $LOG echo "File size summary:" >> $LOG printSize $CLASS >> $LOG printSize $JAR >> $LOG printSize $PRO >> $LOG printSize $PACK >> $LOG printSize $PRO_PACK >> $LOG printSize $PRO_PACK_7ZIP >> $LOG printSize $PRO_PACK_K_GZ >> $LOG echo >> $LOG popd >> /dev/null
import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.EOFException; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; // Based on http://www.gzip.org/zlib/rfc-gzip.html // and http://www.pkware.com/documents/casestudies/APPNOTE.TXT public class Zip2Gzip { // Usage: java Zip2Gzip [file.zip [file.gzip]] public static void main(final String[] args) throws IOException { InputStream in = new FileInputStream(args[0]); in = new BufferedInputStream(in); OutputStream out = new FileOutputStream(args[1]); out = new BufferedOutputStream(out); // Start by writing a gzip header. // Magic. out.write(0x1f); out.write(0x8b); // Compression method: inflate. out.write(0x08); // Flags: we include no optional extras. out.write(0x00); // Timestamp: unavailable. out.write(0x00); out.write(0x00); out.write(0x00); out.write(0x00); // Extra flags: none. out.write(0x00); // OS: unknown. out.write(0xff); // The next block of output is the compressed data. We need to process // the zip file header to find it and know how long it is. // local file header signature 4 bytes (0x04034b50) // version needed to extract 2 bytes // general purpose bit flag 2 bytes // compression method 2 bytes // last mod file time 2 bytes // last mod file date 2 bytes // Total so far: 14 bytes for (int i = 0; i < 14; i++) { in.read(); } // crc-32 4 bytes final int crc1 = in.read(); final int crc2 = in.read(); final int crc3 = in.read(); final int crc4 = in.read(); // compressed size 4 bytes int cmpSz = (in.read() & 0xff) + ((in.read() & 0xff) << 8) + ((in.read() & 0xff) << 16) + ((in.read() & 0xff) << 24); // uncompressed size 4 bytes final int ucmpSz1 = in.read(); final int ucmpSz2 = in.read(); final int ucmpSz3 = in.read(); final int ucmpSz4 = in.read(); // file name length 2 bytes final int nameLen = (in.read() & 0xff) + ((in.read() & 0xff) << 8); // extra field length 2 bytes final int xfLen = (in.read() & 0xff) + ((in.read() & 0xff) << 8); // file name (variable size) for (int i = 0; i < nameLen; i++) { in.read(); } // extra field (variable size) for (int i = 0; i < xfLen; i++) { in.read(); } // Data follows, so we can copy it to the output. final byte[] buf = new byte[4096]; while (cmpSz > 0) { final int desired = cmpSz > buf.length ? buf.length : cmpSz; final int len = in.read(buf, 0, desired); if (len == 0) { throw new EOFException(); } out.write(buf, 0, len); cmpSz -= len; } // The output still needs the CRC32 and the uncompressed size. out.write(crc1); out.write(crc2); out.write(crc3); out.write(crc4); out.write(ucmpSz1); out.write(ucmpSz2); out.write(ucmpSz3); out.write(ucmpSz4); // Done. Be tidy. out.close(); in.close(); } }
Comments