Bitmask vs. booleans?

I’m wondering if the class file is less in bytes if I were to implement the player controls (SHOOT,FORWARD,REVERSE,TURN_RIGHT,TURN_LEFT) in a single bitmask value (1,2,4,8,16) rather than defining 5 boolean variables as class member vars?

Which one is better, for the 4k games?

For mouse and key input, I use this :-


   static final int MOUSE_MODIFIERS = 0;
   static final int MOUSE_X = 1;
   static final int MOUSE_Y = 2;
   
   static final int KEY_START_INDEX = 0; //because no keys on the keyboard map to ASCII 0,1 or 2 this can be safely set to 0
   int [] controls = new int[256+KEY_START_INDEX];

   public final void processEvent(AWTEvent e)
   {
      int [] ctrls = controls;
      if(e instanceof KeyEvent)
      {
         ctrls[(((KeyEvent)e).getKeyCode()&0xFF) +KEY_START_INDEX] = e.getID()&1
      }
      else
      {
         MouseEvent mouse = (MouseEvent)e;
         ctrls[MOUSE_MODIFIERS]=mouse.getModifiersEx();
         ctrls[MOUSE_X]=mouse.getX();
         ctrls[MOUSE_Y]=mouse.getY();
      }
   }

I was thinking more on the lines of:

(functional)


import java.awt.Canvas;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferStrategy;

import javax.swing.JFrame;
import javax.swing.JPanel;

public class Test extends Canvas implements KeyListener {
	private static final int
	FIRE = 1,
	FORWARD = 2,
	REVERSE = 4,
	TURN_LEFT = 8,
	TURN_RIGHT = 16;

	private int ACTION = 0;

	public static void main(String[] args) {
		new Test();
	}
	
	public Test() {
		JFrame w = new JFrame("Test");
		JPanel p = (JPanel)w.getContentPane();
		p.setSize(640,480);
		p.add(this);
		w.setBounds(0,0,640,480); 
		w.setVisible(true);
		w.setResizable(false);
		w.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		addKeyListener(this);
		requestFocus();
		
		createBufferStrategy(2);
		BufferStrategy strategy = getBufferStrategy();
		Graphics2D g = (Graphics2D)strategy.getDrawGraphics();

		
		
		
		while(true) {
			g.setColor(Color.WHITE);
			g.fillRect(0,0,640,480);
			
			g.setColor(Color.BLACK);
			if((ACTION&FIRE)==FIRE)
				g.drawString("User is firing.",20,20);
	
			if((ACTION&FORWARD)==FORWARD)
				g.drawString("User is going forward.",20,40);
	
			if((ACTION&REVERSE)==REVERSE)
				g.drawString("User is reversing.",20,60);
	
			if((ACTION&TURN_LEFT)==TURN_LEFT)
				g.drawString("User is turning left.",20,80);
			
			if((ACTION&TURN_RIGHT)==TURN_RIGHT)
				g.drawString("User is turning right.",20,100);
			
			g.drawString("Action value is :"+ACTION+"\n\n",20,120);
		
			strategy.show();
			
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		
		}
	}
		
		
	public void keyTyped(KeyEvent arg0) {
	}

	public void keyPressed(KeyEvent arg0) {
		switch(arg0.getKeyCode()) {
		case KeyEvent.VK_SPACE: ACTION = ACTION | FIRE; break;
		case KeyEvent.VK_W: ACTION = ACTION | FORWARD; break;
		case KeyEvent.VK_S: ACTION = ACTION | REVERSE; break;
		case KeyEvent.VK_A: ACTION = ACTION | TURN_LEFT; break;
		case KeyEvent.VK_D: ACTION = ACTION | TURN_RIGHT; break;
		}
	}

	public void keyReleased(KeyEvent arg0) {
		switch(arg0.getKeyCode()) {
		case KeyEvent.VK_SPACE: ACTION = ACTION ^ FIRE; break;
		case KeyEvent.VK_W: ACTION = ACTION ^ FORWARD; break;
		case KeyEvent.VK_S: ACTION = ACTION ^ REVERSE; break;
		case KeyEvent.VK_A: ACTION = ACTION ^ TURN_LEFT; break;
		case KeyEvent.VK_D: ACTION = ACTION ^ TURN_RIGHT; break;
		}
	}
}


Mhh, in case you are considering Java 5.0, I would definitly go with enums:


public enum Actions { SHOOT,FORWARD,REVERSE,TURN_RIGHT,TURN_LEFT };
Action action = Actions.SHOOT;
...

It’s more readable and you will be less likely to make a mistake. Adding another action
such as FIRE_ROCKET is easy. And there will be no performance problems in case
you were wondering about that.

This is a 4k contest, not a OO design challenge.

Anyway, maybe the compiler is smart enough, but I’d think that
ACTION = ACTION | SHOOT;
takes more bytes than
ACTION |= SHOOT;

Give it a try.

My same thought.

No 1.5, see the rules thread.

and see the actual rules page: http://javaunlimited.net/contests/java4k.php

Try both ways in a test file and see which class file ends up being bigger.

Third “General Tip” on the 4K Design Article is:

[quote]Don’t use global variables. Global variables require special meta-data in the class to identify. Method-local variables, however, are only stack entries and cost nothing extra to use.
[/quote]
Using bitwise flags would probably cost you more space in extra operations than just using a few booleans. Remember, the stack is essentially free.

BTW: You’re micro-optimizing. That’s a bad thing to do. Try to get your file size down in other ways. Smarter algos, better compression, reduction in method count, etc, are all methods with a far better cost/return ratio.

[quote]public enum Actions { SHOOT,FORWARD,REVERSE,TURN_RIGHT,TURN_LEFT };
[/quote]
That’s a REALLY bad idea. I almost guarantee that such a trick would bloat the class with tons of unnecessary meta-data. Just think, each of those names is going to be stored somewhere in the class file! That’s at least 39 bytes that you’re never getting back. Much more once you start creating references to these objects in your code.