001package squidpony.squidmath; 002 003/** 004 * An interface for "point hashes", that is, functions that produce usually-unique integer results given multiple 005 * integer inputs. The hash functions this guarantees an implementor will provide all take int inputs and return an int. 006 * There are lots of cases where an implementor would have other functions that take long inputs or return longs, and in 007 * those cases the interface methods would probably be implemented by delegating to the long inputs and/or casting the 008 * result to a long. Implementors must have a {@link #setState(int)} function, but it doesn't have to do anything if the 009 * algorithm doesn't support a state; similarly, {@link #hashWithState(int, int, int)} can return the same thing as 010 * {@link #hash(int, int)} if states aren't supported. If states are supported, then calling {@link #hash(int, int)} 011 * while the state is, for example, 42 should be the same as calling {@link #hashWithState(int, int, int)} with a state 012 * parameter of 42 (regardless of what the state actually is in the implementor). 013 * <br> 014 * Created by Tommy Ettinger on 4/13/2020. 015 */ 016public interface IPointHash { 017 void setState(int state); 018 int hash(int x, int y); 019 int hash(int x, int y, int z); 020 int hash(int x, int y, int z, int w); 021 int hash(int x, int y, int z, int w, int u, int v); 022 int hashWithState(int x, int y, int state); 023 int hashWithState(int x, int y, int z, int state); 024 int hashWithState(int x, int y, int z, int w, int state); 025 int hashWithState(int x, int y, int z, int w, int u, int v, int state); 026 027 /** 028 * A convenience abstract class to implement IPointHash when you have an int for state. Subclasses will need to 029 * implement {@link #hashWithState(int, int, int)}, {@link #hashWithState(int, int, int, int)}, 030 * {@link #hashWithState(int, int, int, int, int)}, and {@link #hashWithState(int, int, int, int, int, int, int)}. 031 * They can optionally override {@link #setState(int)}, and can at their discretion provide an accessor for the 032 * protected int {@link #state}. 033 */ 034 abstract class IntImpl implements IPointHash { 035 protected int state = 42; 036 public IntImpl(){ 037 setState(42); 038 } 039 public IntImpl(int state){ 040 setState(state); 041 } 042 043 @Override 044 public void setState(int state) { 045 this.state = state; 046 } 047 048 @Override 049 public int hash(int x, int y) { 050 return hashWithState(x, y, state); 051 } 052 053 @Override 054 public int hash(int x, int y, int z) { 055 return hashWithState(x, y, z, state); 056 } 057 058 @Override 059 public int hash(int x, int y, int z, int w) { 060 return hashWithState(x, y, z, w, state); 061 } 062 063 @Override 064 public int hash(int x, int y, int z, int w, int u, int v) { 065 return hashWithState(x, y, z, w, u, v, state); 066 } 067 } 068 /** 069 * A convenience abstract class to implement IPointHash when you have a long for state. Subclasses will need to 070 * implement {@link #hashWithState(int, int, int)}, {@link #hashWithState(int, int, int, int)}, 071 * {@link #hashWithState(int, int, int, int, int)}, and {@link #hashWithState(int, int, int, int, int, int, int)}. 072 * They can optionally override {@link #setState(int)} or {@link #setState(long)}, and can at their discretion 073 * provide an accessor for the protected long {@link #state}. 074 */ 075 abstract class LongImpl implements IPointHash { 076 protected long state = 42; 077 public LongImpl(){ 078 setState(42); 079 } 080 public LongImpl(int state){ 081 setState(state); 082 } 083 public LongImpl(long state){ 084 setState(state); 085 } 086 087 @Override 088 public void setState(int state) { 089 this.state = state; 090 } 091 092 public void setState(long state){ 093 this.state = state; 094 } 095 096 @Override 097 public int hash(int x, int y) { 098 return hashWithState(x, y, (int) (state ^ state >>> 32)); 099 } 100 101 @Override 102 public int hash(int x, int y, int z) { 103 return hashWithState(x, y, z, (int) (state ^ state >>> 32)); 104 } 105 106 @Override 107 public int hash(int x, int y, int z, int w) { 108 return hashWithState(x, y, z, w, (int) (state ^ state >>> 32)); 109 } 110 111 @Override 112 public int hash(int x, int y, int z, int w, int u, int v) { 113 return hashWithState(x, y, z, w, u, v, (int) (state ^ state >>> 32)); 114 } 115 } 116}