When I was young I knew a guy who played the lottery a lot and firmly believed that his odds were higher if he put his money on numbers that had not come up in a long time. In other word he thought random systems tend “catch up” to become balanced, but this is of course totally fails. Random systems are only balanced over an infinite sample.
Before I go any further I should note that I am not an expert on any of this stuff. I don’t know much about the theory of randomness or the methods of it’s creation. This is just my own thoughts.
A lot of people seem to have strange ideas of what “random” is. For instance, look at the Dice-O-Matic built for GamesByEmail.com. It is a mechanical dice roller and is a really fun project BTW. I don’t mean to put it down at all with this post, I just don’t really understand why people would like it is better than a computer based random number generator (true or pseudo). It was built because users of the site complained that the computer generated dice rolls where not random enough. The sources he used were standard pseudo-random number generators and also true random number generators like random.org. PRNGs are certainly not random but over the sample size used on board games it seems very unlikely to me that anyone could detect the non-randomness. And if you introduce something like random.org you have random numbers generated by such a huge system (the earths atmosphere) that they would almost certainly be more random than dice rolling on a table (especially the cheap dice that come with most games).
My suspicion is that people felt like they were getting too many low rolls. But that happens in random systems. Anything can happen; that’s what random means.
There are many ways to build table top true random number generator. Many of them much smaller than a dice rolling machine (and probably more random). For instance:
Here are instuctions for building a small device that detects the alpha emitions from a sample of americonium (from a smoke detector): Alpha Radiation Visualizer. The output of this will be very random (the radiation is a quantum process).
Here is a chaotic circuit that can be sampled to produce random numbers: Make your own True Random Number Generator 2. This TRNG is not quantum (I don’t think) but it is highly chaotic and should be a good source of random bits.
[EDIT] There is also LavaRnd. Which looks much better designed than any of the other ones I mentioned. Though I think either of the above hardware devices could be used as good input into the LavaRnd algorythms.
Posted in
Hardware
Ray casting is an old rendering technique used in early “3D” games like Wolfenstein 3D. Today it is nothing much, but implementing it will test your knowledge of trig and binary rounding issues. The real reason I wrote it though was because I have tried to implment a raycasting engine several times before and failed. Until now! So it was a matter of geek pride to go back to this problem and defeat it.
I implemented the engine in as functional a way as possible. I think it came out fairly well. I did not optimize anything for performance. So I used Double values for the most part. This is very different than most implementations you see online that implement the entire algorithm with ints and use look up tables for the trig functions. One issue that I had run into before is that because parts of the algorithm are fundamentally quantized (the map cells) floating point can actually cause problems like disappearing walls or holes in walls. I was able to work around these issues through the creative use of rounding and a fudge factor (to make sure the value was on the correct side of a boundry). Regardless it works now and I’m glad I defeated the algorithm.
The project is available in github:
Posted in
Scala
I was just reminded of something that I often forget. So I thought I’d mention it here.
When the JVM (at least Sun’s HotSpot) optimizes a method it will only create one optimized version. So that if more than one type of object is passed to the function it will prevent inlineing and other optimization. This means you have to be conscious of what you allow to be passed into methods that should be optimized since the compiler will optimize for the lowerest common denominator of all input values.
This is standard for JITs. However as a side note, there are JITs that do produce multiple optimized versions for functions that are used in more than one context. One example is Psyco. Work on Psyco has stopped and new development is going into PyPy which is a fascinating (and kind of deranged) project.
Posted in
JVM
I was thinking about the future of Google street view and I realized something. One of the really nice things about the street view is that the images are pretty recent. However that will change. They are spending a lot of money to capture all these images, but I doubt they will want to spend that again to recapture them in 2 years.
So: will Google street view decline in usefulness as the images age? Or will Google update them? Or will the old images still be just as useful?
I wonder if Google might keep track of construction projects and reimage area based on how much they have been changed.
PS: They get some odd pictures too: Top 10 Moments Caught on Google Maps Street View
Posted in
Uncategorized
I have been using Metawidget (which is a really cool library by the way) on a project lately. I wanted to avoid the need for a save button by having changes automatically propagated to the beans when changes are made to the widgets. However I am using BeanUtils (from apache) which does not support binding internally.
I did try BeanBinding but it was really slow (I don’t know why and I didn’t have time to debug it). So I created an extension to the BeanUtilsBinding class (from Metawidget) that adds auto-save support. It’s a really ugly hackish implementation but it works reliably (though I think there may be corner cases where the save does not trigger when it should). It is also quite fast. It doesn’t run the save until all the messages currently in the swing queue are processed (using SwingUtilities.invokeLater
) and then it only runs it once so even if a lot of changes happen at the same time only one save will be done.
The implementation is below. Feel free to use it. It is copyright Arthur Peters under the GNU GPL v3.
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.EventListener;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.SwingUtilities;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import org.metawidget.swing.SwingMetawidget;
import org.metawidget.swing.propertybinding.beanutils.BeanUtilsBinding;
public class BeanUtilsAutoUpdateBinding extends BeanUtilsBinding {
@SuppressWarnings("unused")
private static final Logger log = Logger
.getLogger("BeanUtilsAutoUpdateBinding");
protected static final class ListenToRecord {
private final Component component;
private final String propertyName;
public ListenToRecord(Component component, String propertyName) {
this.component = component;
this.propertyName = propertyName;
}
public Component getComponent() {
return component;
}
public String getPropertyName() {
return propertyName;
}
}
private List listeningTo = new ArrayList();
private ChangeListener changeListener = new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
doSave();
}
};
private ActionListener actionListener = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
doSave();
}
};
/*private DocumentListener documentListener = new DocumentListener() {
@Override
public void changedUpdate(DocumentEvent e) {
doSave();
}
@Override
public void insertUpdate(DocumentEvent e) {
doSave();
}
@Override
public void removeUpdate(DocumentEvent e) {
doSave();
}
};
*/
private KeyListener keyListener = new KeyListener() {
@Override
public void keyPressed(KeyEvent e) {
doSave();
}
@Override
public void keyReleased(KeyEvent e) {
doSave();
}
@Override
public void keyTyped(KeyEvent e) {
doSave();
}
};
private MouseListener mouseListener = new MouseListener() {
@Override
public void mouseClicked(MouseEvent e) {
doSave();
}
@Override
public void mouseEntered(MouseEvent e) {
// Ignore
}
@Override
public void mouseExited(MouseEvent e) {
// Ignore
}
@Override
public void mousePressed(MouseEvent e) {
// Ignore
}
@Override
public void mouseReleased(MouseEvent e) {
doSave();
}
};
private FocusListener focusListener = new FocusListener() {
@Override
public void focusGained(FocusEvent e) {
// Ignore
}
@Override
public void focusLost(FocusEvent e) {
doSave();
}
};
private boolean saveAlreadyInEventQueue;
public BeanUtilsAutoUpdateBinding(SwingMetawidget metawidget) {
super(metawidget);
}
@Override
public void bindProperty(Component component,
Map attributes, String path) {
super.bindProperty(component, attributes, path);
String valueProperty = getMetawidget().getValueProperty(component);
// component.addPropertyChangeListener(valueProperty, this);
attemptToCall(component, "addChangeListener", ChangeListener.class,
changeListener);
attemptToCall(component, "addActionListener", ActionListener.class,
actionListener);
// attemptToCall(component, "addDocumentListener",
// DocumentListener.class, documentListener);
component.addKeyListener(keyListener);
component.addMouseListener(mouseListener);
component.addFocusListener(focusListener);
listeningTo.add(new ListenToRecord(component, valueProperty));
}
private void attemptToCall(Component component, String methodName,
Class eventListenerCls,
EventListener eventListener) {
try {
Class cls = component.getClass();
Method method = null;
while (method == null && cls != Object.class) {
try {
method = cls.getMethod(methodName, eventListenerCls);
} catch (NoSuchMethodException e) {
// Ignore
}
cls = cls.getSuperclass();
}
method.invoke(component, eventListener);
} catch (Exception e) {
// Ignore it and return. This function is an attempt.
log.log(Level.FINE, "Failed to call " + methodName + " on "
+ component, e);
}
}
@Override
public void unbindProperties() {
super.unbindProperties();
for (ListenToRecord listenToRecord : listeningTo) {
Component component = listenToRecord.getComponent();
// component.removePropertyChangeListener(listenToRecord.getPropertyName(),
// this);
component.removeKeyListener(keyListener);
component.removeMouseListener(mouseListener);
attemptToCall(component, "removeChangeListener",
ChangeListener.class, changeListener);
attemptToCall(component, "removeActionListener",
ActionListener.class, actionListener);
// attemptToCall(component, "removeDocumentListener",
// DocumentListener.class, documentListener);
}
listeningTo.clear();
}
protected void doSave() {
synchronized (this) {
if (!saveAlreadyInEventQueue) {
saveAlreadyInEventQueue = true;
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
getMetawidget().save();
synchronized (BeanUtilsAutoUpdateBinding.this) {
saveAlreadyInEventQueue = false;
}
}
});
}
}
}
}
Posted in
Java,
Programming