Author: bdonlan
Date: 2005-01-14 20:36:45 -0500 (Fri, 14 Jan 2005)
New Revision: 599

Added:
   trunk/misc/javer/src/javer/CMod.java
   trunk/misc/javer/src/javer/GameMod.java
   trunk/misc/javer/src/javer/TimedInvoker.java
   trunk/misc/javer/src/javer/TimerThread.java
Modified:
   trunk/misc/javer/
Log:
 [EMAIL PROTECTED]:  bdonlan | 2005-01-14 20:34:20 -0500
 Import of Haver CMod. This should probably be moved into a seperate project.



Property changes on: trunk/misc/javer
___________________________________________________________________
Name: svk:merge
   - 1f59643a-e6e5-0310-bc24-f7d4c744f460:/haver/local/trunk/misc/javer:16424
   + 1f59643a-e6e5-0310-bc24-f7d4c744f460:/haver/local/trunk/misc/javer:16426

Added: trunk/misc/javer/src/javer/CMod.java
===================================================================
--- trunk/misc/javer/src/javer/CMod.java        2005-01-14 21:07:21 UTC (rev 
598)
+++ trunk/misc/javer/src/javer/CMod.java        2005-01-15 01:36:45 UTC (rev 
599)
@@ -0,0 +1,177 @@
+/*
+ * CMod.java
+ *
+ * Created on January 14, 2005, 7:03 PM
+ */
+
+package javer;
+import java.util.*;
+import java.io.*;
+import java.math.*;
+
+/**
+ *
+ * @author bdonlan
+ */
+public class CMod extends GameMod {
+    
+    boolean conspiracyExists = false;
+    boolean polling = false;
+    String innocent = null;
+    Map pollresults = null;
+    String homechannel;
+    Object pollTimer = null;
+    
+    /** Creates a new instance of CMod */
+    public CMod(String homechannel) {
+        super();
+        this.homechannel = homechannel;
+    }
+
+    protected void eventPrivateNormalMessage(String who, String arg) throws 
java.io.IOException {
+        if (polling) {
+            String val = arg.toLowerCase();
+            boolean choice;
+            if (val.equals("yes"))
+                choice = true;
+            else if (val.equals("no"))
+                choice = false;
+            else {
+                sendPrivateNormalMessage(who, "Huh?");
+                super.eventPrivateNormalMessage(who, arg);
+                return;
+            }
+            if (pollresults.containsKey(who)) {
+                sendPrivateNormalMessage(who, "You cannot change your 
choice.");
+            } else {
+                Boolean value = new Boolean(choice);
+                pollresults.put(who, value);
+                sendPrivateNormalMessage(who, "Noted.");
+                if (pollresults.size() == players.size()) {
+                    tallyResults();
+                }
+            }
+        }
+        super.eventPrivateNormalMessage(who, arg);
+    }
+
+    protected void eventIdentAccepted() throws java.io.IOException {
+        super.eventIdentAccepted();
+        join(homechannel);
+    }
+
+    public void endGame() throws java.io.IOException {
+        polling = false;
+        if (pollTimer != null) {
+            TimedInvoker.unschedule(pollTimer);
+        }
+        pollresults = null;
+        innocent = null;
+        pollTimer = null;
+        super.endGame();
+    }
+
+    public void beginGame() throws java.io.IOException {
+        Random r = new Random();
+        conspiracyExists = r.nextBoolean();
+        if (conspiracyExists) {
+            Object[] playerarray = players.toArray();
+            innocent = (String)playerarray[r.nextInt(playerarray.length)];
+        }
+        Iterator pi = players.iterator();
+        while (pi.hasNext()) {
+            String uid = (String)pi.next();
+            if (uid.equals(innocent) || !conspiracyExists) {
+                sendPrivateNormalMessage(uid, "You are an innocent in this 
game.");
+            } else {
+                sendPrivateNormalMessage(uid, "You are a conspirator, and the 
innocent is " + innocent);
+            }
+        }
+        sendNormalMessage(homechannel, "A game of Conspiracy has begun! You 
have 10 minutes before polling phase begins.");
+        pollTimer = TimedInvoker.invokeAfter(10 * 60 * 1000, new Runnable() {
+            public void run() {
+                try {
+                    beginPolling();
+                } catch (IOException e) {
+                    eventIOException(e);
+                }
+            }
+        });
+        super.beginGame();
+    }
+    
+    protected void beginPolling() throws IOException {
+        if (!playing)
+            return;
+        sendNormalMessage(homechannel, "Time's up! Please /msg me with 'yes'" +
+                " if you think there is a conspiracy, or 'no' if you believe" +
+                " there is no conspiracy.");
+        pollresults = new HashMap(players.size());
+        polling = true;
+    }
+    
+    protected void tallyResults() throws IOException {
+        Set winners;
+        if (conspiracyExists) {
+            boolean innocentWins;
+            innocentWins = ((Boolean)pollresults.get(innocent)).booleanValue();
+            if (innocentWins)
+                winners = Collections.singleton(innocent);
+            else {
+                winners = new HashSet(players);
+                winners.remove(innocent);
+            }
+        } else {
+            Iterator it = players.iterator();
+            winners = new HashSet();
+            while (it.hasNext()) {
+                String uid = (String)it.next();
+                Boolean result = (Boolean)pollresults.get(uid);
+                if (!result.booleanValue())
+                    winners.add(uid);
+            }
+        }
+        Iterator it = players.iterator();
+        sendNormalMessage(homechannel, 
+                "All polls are in. The results are as follows:");
+        /* field lengths: nick 15, poll 3, win 3 */
+        sendNormalMessage(homechannel, 
+                "NICK            RES WIN");
+        sendNormalMessage(homechannel,
+                "=======================");
+        while (it.hasNext()) {
+            String uid = (String)it.next();
+            String nick = (String)channelMembers.get(uid);
+            boolean won = winners.contains(uid);
+            boolean vote = ((Boolean)pollresults.get(uid)).booleanValue();
+            while(nick.length() < 15) {
+                nick = nick + " ";
+            }
+            String msg = nick;
+            if (vote)
+                msg = msg + "  Y ";
+            else
+                msg = msg + "  N ";
+            if (won)
+                msg = msg + "  Y ";
+            else
+                msg = msg + "  N ";
+            sendNormalMessage(homechannel, msg);
+        }
+        sendNormalMessage(homechannel,
+                "=======================");
+        sendNormalMessage(homechannel,
+                "Game over. Thanks for playing!");
+        endGame();
+    }
+    
+    public static void main(String[] args) throws Exception {
+        CMod mod = new CMod(args[3]);
+        mod.connect(args[0], args[1], Integer.decode(args[2]).intValue());
+    }
+
+    protected void eventDebugMessage(String s) throws IOException {
+        //log("DEBUG", s);
+        super.eventDebugMessage(s);
+    }
+}


Property changes on: trunk/misc/javer/src/javer/CMod.java
___________________________________________________________________
Name: svn:eol-style
   + native

Added: trunk/misc/javer/src/javer/GameMod.java
===================================================================
--- trunk/misc/javer/src/javer/GameMod.java     2005-01-14 21:07:21 UTC (rev 
598)
+++ trunk/misc/javer/src/javer/GameMod.java     2005-01-15 01:36:45 UTC (rev 
599)
@@ -0,0 +1,154 @@
+/*
+ * GameMod.java
+ *
+ * Created on January 14, 2005, 6:16 PM
+ */
+
+package javer;
+import java.util.*;
+import java.io.*;
+
+/**
+ *
+ * @author bdonlan
+ */
+public abstract class GameMod extends HaverClient {
+        
+    protected boolean connected = false;
+    protected boolean joined = false;
+    protected boolean playing = false;
+    protected boolean starting = false;
+    protected String channel = null;
+    protected Map channelMembers = null; /* UID -> nick */
+    protected Set players = null; /* UID */
+    protected Object joinTimer = null;
+    
+    /** Creates a new instance of GameMod */
+    protected GameMod() {
+    }
+
+    protected void log(String level, String message) {
+        System.err.println(level + ": " + message);
+    }
+    
+    public void dropPlayer(String requestor, String dropee) {
+        /* TODO */
+    }
+    
+    protected void eventChannelPart(String where) throws IOException {
+        joined = false;
+        endGame();
+        channelMembers = null;
+        channel = null;
+        super.eventChannelPart(where);
+    }
+
+    protected void eventChannelJoin(String where) throws IOException {
+        if (joined) {
+            log("CRITICAL", "Joined an extra channel: " + where);
+            return;
+        }
+        joined = true;
+        channel = where;
+        listChannel(where);
+        super.eventChannelJoin(where);
+    }
+
+    protected boolean eventIOException(IOException e) {
+
+        boolean retValue;
+        
+        retValue = super.eventIOException(e);
+        return retValue;
+    }
+
+    protected void eventIdentFailed(String why, String[] args) throws 
IOException {
+
+        super.eventIdentFailed(why, args);
+    }
+
+    protected void eventChannelList(String where, Set names) throws 
IOException {
+        Iterator it = names.iterator();
+        if (!where.equals(channel))
+            return;
+        channelMembers = new HashMap();
+        while (it.hasNext()) {
+            Object o = it.next();
+            channelMembers.put(o,o);
+        }
+        super.eventChannelList(where, names);
+    }
+
+    protected void eventNormalMessage(String where, String who, String arg) 
throws IOException {
+        if (arg.equals("!join") && starting) {
+            if (players.contains(who)) {
+                sendPrivateNormalMessage(who, "You are already registered.");
+            } else {
+                players.add(who);
+                sendPrivateNormalMessage(who, "You are now registered.");
+            }
+        } else if (arg.equals("!abort") && (starting || playing)) {
+            abortGame();
+        } else if (arg.indexOf("!drop") == 0 && (starting || playing)) {
+            if (arg.length() == 0) {
+                dropPlayer(who, who);
+            } else {
+                if (arg.indexOf("!drop ") == 0) {
+                    int i = "!drop ".length();
+                    for (; i < arg.length(); i++) {
+                        if (arg.charAt(i) != ' ')
+                            break;
+                    }
+                    if (i != arg.length()) {
+                        dropPlayer(who, arg.substring(i));
+                    }
+                }
+            }
+        } else if (arg.equals("!start") && !(playing || starting)) {
+            starting = true;
+            players = new HashSet();
+            sendNormalMessage(where, "A new game has begun. Type !join in the 
next 30 seconds to join.");
+            joinTimer = TimedInvoker.invokeAfter(30 * 1000, new Runnable() {
+                public void run () {
+                    try {
+                        beginGame();
+                    } catch (IOException e) {
+                        eventIOException(e);
+                    } catch (Exception e) {
+                        e.printStackTrace();
+                    }
+                    joinTimer = null;
+                }
+            });
+        }
+        super.eventNormalMessage(where, who, arg);
+    }
+
+    protected void eventDisconnected() throws IOException {
+        endGame();
+        super.eventDisconnected();
+    }
+
+    protected void eventIdentAccepted() throws IOException {
+        connected = true;
+        super.eventIdentAccepted();
+    }
+    
+    public void endGame() throws IOException {
+        playing = starting = false;
+        players = null;
+        if (joinTimer != null) {
+            TimedInvoker.unschedule(joinTimer);
+            joinTimer = null;
+        }
+    }
+    
+    public void abortGame() throws IOException {
+        endGame();
+        sendNormalMessage(channel, "Game aborted");
+    }
+    
+    public void beginGame() throws IOException {
+        playing = true;
+    }
+}


Property changes on: trunk/misc/javer/src/javer/GameMod.java
___________________________________________________________________
Name: svn:eol-style
   + native

Added: trunk/misc/javer/src/javer/TimedInvoker.java
===================================================================
--- trunk/misc/javer/src/javer/TimedInvoker.java        2005-01-14 21:07:21 UTC 
(rev 598)
+++ trunk/misc/javer/src/javer/TimedInvoker.java        2005-01-15 01:36:45 UTC 
(rev 599)
@@ -0,0 +1,37 @@
+/*
+ * TimedInvoker.java
+ *
+ * Created on January 14, 2005, 7:40PM
+ */
+
+package javer;
+import java.util.*;
+import java.io.*;
+import java.math.*;
+
+/**
+ *
+ * @author bdonlan
+ */
+final class TimedInvoker {
+    
+    static TimerThread tt = new TimerThread();
+    
+    private TimedInvoker() {
+        throw new IllegalStateException("Cannot instantiate a singleton 
class");
+    }
+    
+    public static Object invokeAt(long absoluteTimeMillis, Runnable invokee) {
+        return tt.addTimer(absoluteTimeMillis, invokee);
+    }
+    
+    public static Object invokeAfter(long deltaMillis, Runnable invokee) {
+        return tt.addTimer(System.currentTimeMillis() + deltaMillis,
+                invokee);
+    }
+    
+    public static boolean unschedule(Object tag) {
+        return tt.cancelTimer(tag);
+    }
+    
+}
\ No newline at end of file


Property changes on: trunk/misc/javer/src/javer/TimedInvoker.java
___________________________________________________________________
Name: svn:eol-style
   + native

Added: trunk/misc/javer/src/javer/TimerThread.java
===================================================================
--- trunk/misc/javer/src/javer/TimerThread.java 2005-01-14 21:07:21 UTC (rev 
598)
+++ trunk/misc/javer/src/javer/TimerThread.java 2005-01-15 01:36:45 UTC (rev 
599)
@@ -0,0 +1,118 @@
+/*
+ * TimerThread.java
+ *
+ * Created on January 14, 2005, 7:47 PM
+ */
+
+package javer;
+import java.util.*;
+
+/**
+ *
+ * @author bdonlan
+ */
+class TimerThread implements Runnable {
+
+    class Timer {
+        Runnable evt;
+        long when;
+    }
+
+    Thread thread = null;
+    SortedMap queue = new TreeMap();
+
+    protected void notifyThread() {
+        synchronized (queue) {
+            if (thread == null || !thread.isAlive()) {
+                thread = new Thread(this);
+                //System.out.println("TT: spawning");
+                thread.start();
+                return;
+            }
+            //System.out.println("TT: interrupting");
+            thread.interrupt();
+        }
+    }
+
+    protected synchronized Object addTimer(long when, Runnable event) {
+        Set slot;
+        Timer te = new Timer();
+        Long oWhen = new Long(when);
+        te.evt = event;
+        te.when = when;
+        synchronized (queue) {
+            slot = (Set)queue.get(oWhen);
+            if (slot == null) {
+                slot = new LinkedHashSet();
+            }
+            slot.add(te);
+            queue.put(oWhen, slot);
+            //System.out.println("TT: add queuelen=" + queue.size());
+            //System.out.println("TT: add slotlen=" + slot.size());
+            notifyThread();
+        }
+        return te;
+    }
+
+    protected synchronized boolean cancelTimer(Object tag) {
+        Timer te = (Timer) tag;
+        Long when = new Long(te.when);
+        synchronized (queue) {
+            Set slot = (Set)queue.get(when);
+            if (slot == null)
+                return false;
+            slot.remove(te);
+            if (slot.isEmpty())
+                queue.remove(when);
+            /* We don't need to notify the thread; if this slot is next then
+             * the thread will just go back to sleep or die once it discovers
+             * the first slot time has changed.
+             */
+            return true;
+        }
+    }
+
+    public void run() {
+        if (Thread.currentThread() != thread)
+            return;
+        while (true) {
+            long nextSlot, delta, now;
+            Set slot = null;
+            now = System.currentTimeMillis();
+            synchronized (queue) {
+                Long firstkey;
+                if (queue.size() == 0) {
+                    /* No work? We die. */
+                    //System.out.println("TT: no work, killing thread");
+                    thread = null;
+                    return;
+                }
+                firstkey = (Long)queue.firstKey();
+                nextSlot = firstkey.longValue();
+                //System.out.println("TT: nxS=" + nextSlot + "\nTT: now=" + 
now);
+                if (nextSlot <= now) {
+                    //System.out.println("TT: pop=" + nextSlot);
+                    slot = (Set) queue.remove(firstkey);
+                }
+            }
+            if (slot != null) {
+                Iterator it = slot.iterator();
+                //System.out.println("TT: slotsize=" + slot.size());
+                while (it.hasNext()) {
+                    Timer te = (Timer)it.next();
+                    //System.out.println("TT: invokeLater("+te.evt+")");
+                    java.awt.EventQueue.invokeLater(te.evt);
+                }
+                continue;
+            }
+            delta = nextSlot - now;
+            try {
+                thread.sleep(delta);
+            } catch (InterruptedException e) {}
+        }
+    }
+
+    TimerThread() {
+    }
+}
+


Property changes on: trunk/misc/javer/src/javer/TimerThread.java
___________________________________________________________________
Name: svn:eol-style
   + native


Reply via email to