visidor/src/main/java/cz/xelfi/quoridor/visidor/Viewer.java
author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
Thu, 07 Jan 2010 22:34:17 +0100
branchstatistics-and-elo
changeset 178 4b78d4f028b3
parent 33 6a6d1dbea99e
child 248 9bbf25021886
permissions -rw-r--r--
Initial version of statistics and ELO rating. Donated by Martin Rexa
     1 /*
     2  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
     3  *
     4  * The contents of this file are subject to the terms of either the GNU
     5  * General Public License Version 2 only ("GPL") or the Common
     6  * Development and Distribution License("CDDL") (collectively, the
     7  * "License"). You may not use this file except in compliance with the
     8  * License. You can obtain a copy of the License at
     9  * http://www.netbeans.org/cddl-gplv2.html
    10  * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
    11  * specific language governing permissions and limitations under the
    12  * License.  When distributing the software, include this License Header
    13  * Notice in each file and include the License file at
    14  * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
    15  * particular file as subject to the "Classpath" exception as provided
    16  * by Sun in the GPL Version 2 section of the License file that
    17  * accompanied this code. If applicable, add the following below the
    18  * License Header, with the fields enclosed by brackets [] replaced by
    19  * your own identifying information:
    20  * "Portions Copyrighted [year] [name of copyright owner]"
    21  *
    22  * Contributor(s):
    23  *
    24  * Portions Copyrighted 2009 Jaroslav Tulach
    25  */
    26 package cz.xelfi.quoridor.visidor;
    27 
    28 import cz.xelfi.quoridor.Board;
    29 import cz.xelfi.quoridor.Fence;
    30 import cz.xelfi.quoridor.Fence.Orientation;
    31 import cz.xelfi.quoridor.IllegalPositionException;
    32 import cz.xelfi.quoridor.Move;
    33 import cz.xelfi.quoridor.Player;
    34 import java.awt.Color;
    35 import java.awt.Graphics2D;
    36 import java.awt.Point;
    37 import java.awt.Rectangle;
    38 import javax.swing.JFrame;
    39 import javax.swing.JPanel;
    40 import org.netbeans.api.visual.action.ActionFactory;
    41 import org.netbeans.api.visual.action.MoveProvider;
    42 import org.netbeans.api.visual.anchor.AnchorFactory;
    43 import org.netbeans.api.visual.border.BorderFactory;
    44 import org.netbeans.api.visual.widget.ConnectionWidget;
    45 import org.netbeans.api.visual.widget.ImageWidget;
    46 import org.netbeans.api.visual.widget.LabelWidget;
    47 import org.netbeans.api.visual.widget.LayerWidget;
    48 import org.netbeans.api.visual.widget.Scene;
    49 import org.netbeans.api.visual.widget.Widget;
    50 import org.openide.util.Exceptions;
    51 
    52 /**
    53  *
    54  * @author Jaroslav Tulach <jtulach@netbeans.org>
    55  */
    56 final class Viewer extends JPanel {
    57     private Board board;
    58     private final Scene scene;
    59 
    60     public Viewer() {
    61         this(Board.empty());
    62     }
    63 
    64     private Viewer(Board b) {
    65         this.board = b;
    66         this.scene = new Scene();
    67         add(scene.createView());
    68         view(scene, board);
    69     }
    70 
    71 
    72     /**
    73      * @param args the command line arguments
    74      */
    75     public static void main(String[] args) throws IllegalPositionException {
    76         Board b = Board.empty();
    77         for (int i = 1; i <= 8; i++) {
    78             b = b.apply(Move.fence('A', i, Orientation.values()[i % 2]));
    79         }
    80         for (int i = 1; i <= 8; i++) {
    81             b = b.apply(Move.fence('H', i, Orientation.values()[(i + 1) % 2]));
    82         }
    83 
    84         JFrame f = new JFrame();
    85         f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    86         f.add(new Viewer(b));
    87         f.pack();
    88         f.setVisible(true);
    89     }
    90 
    91     private void view(Scene scene, Board b) {
    92         scene.removeChildren();
    93 //        Scene layerBoard = scene;
    94         final LayerWidget layerLines = new LayerWidget(scene);
    95         scene.addChild(layerLines);
    96         final LayerWidget layerBoard = new LayerWidget(scene);
    97         layerLines.addChild(layerBoard);
    98         final int WDTH = 50;
    99         final int HGHT = 50;
   100 //        conn.setSourceAnchor(ahoj);
   101         Widget[][] fields = new Widget[10][];
   102         for (int i = 0; i < fields.length; i++) {
   103             fields[i] = new Widget[10];
   104             for (int j = 0; j < fields[i].length; j++) {
   105                 LabelWidget w = new LabelWidget(scene);
   106                 w.setPreferredBounds(new Rectangle(i * WDTH, j * HGHT, WDTH, HGHT));
   107                 layerBoard.addChild(w);
   108                 fields[i][j] = w;
   109             }
   110         }
   111         for (int i = 0; i < fields.length; i++) {
   112             for (int j = 0; j < fields[i].length; j++) {
   113                 if (i > 0) {
   114                     ConnectionWidget horiz = new ConnectionWidget(scene);
   115                     horiz.setSourceAnchor(AnchorFactory.createCenterAnchor(fields[i - 1][j]));
   116                     horiz.setTargetAnchor(AnchorFactory.createCenterAnchor(fields[i][j]));
   117                     scene.addChild(horiz);
   118                 }
   119                 if (j > 0) {
   120                     ConnectionWidget vert = new ConnectionWidget(scene);
   121                     vert.setSourceAnchor(AnchorFactory.createCenterAnchor(fields[i][j - 1]));
   122                     vert.setTargetAnchor(AnchorFactory.createCenterAnchor(fields[i][j]));
   123                     scene.addChild(vert);
   124                 }
   125             }
   126         }
   127 
   128         ImageWidget horizontalWall = new ImageWidget(scene);
   129         horizontalWall.setPreferredBounds(new Rectangle(550, 300, 90, 10));
   130         horizontalWall.setBackground(Color.BLACK);
   131         horizontalWall.getActions().addAction(ActionFactory.createMoveAction(null, new MoveControl(true)));
   132         horizontalWall.setBorder(BorderFactory.createLineBorder());
   133         horizontalWall.setOpaque(true);
   134         layerBoard.addChild(horizontalWall);
   135 
   136         ImageWidget verticalWall = new ImageWidget(scene);
   137         verticalWall.setPreferredBounds(new Rectangle(600, 150, 10, 90));
   138         verticalWall.setBackground(Color.BLACK);
   139         verticalWall.getActions().addAction(ActionFactory.createMoveAction(null, new MoveControl(false)));
   140         verticalWall.setBorder(BorderFactory.createLineBorder());
   141         verticalWall.setOpaque(true);
   142         layerBoard.addChild(verticalWall);
   143 
   144         for (Fence f : b.getFences()) {
   145             Rectangle r = fenceRectangle(f.getColumn(), f.getRow(), f.getOrientation());
   146             ImageWidget fenceWall = new ImageWidget(scene);
   147             fenceWall.setPreferredBounds(r);
   148             fenceWall.setBackground(Color.BLACK);
   149             fenceWall.setBorder(BorderFactory.createLineBorder());
   150             fenceWall.setOpaque(true);
   151             layerBoard.addChild(fenceWall);
   152         }
   153 
   154         int cnt = 0;
   155         for (Player p : b.getPlayers()) {
   156             LabelWidget lw = new LabelWidget(scene);
   157             lw.setLabel("" + p.getFences());
   158             if (cnt == 0) {
   159                 lw.setPreferredBounds(new Rectangle(550, 200, 50, 50));
   160             } else {
   161                 lw.setPreferredBounds(new Rectangle(550, 450, 50, 50));
   162             }
   163             layerBoard.addChild(lw);
   164 
   165             PlayerWidget pw = new PlayerWidget(scene);
   166             System.err.println("p: " + p);
   167             pw.setPreferredBounds(new Rectangle(p.getColumn() * 50 + 25, p.getRow() * 50 + 25, 50, 50));
   168             layerBoard.addChild(pw);
   169 
   170             cnt++;
   171         }
   172     }
   173 
   174     private static Rectangle fenceRectangle(char column, int row, Fence.Orientation o) {
   175         int w, h;
   176         switch (o) {
   177             case HORIZONTAL: w = 45; h = 5; break;
   178             case VERTICAL: w = 5; h = 45; break;
   179             default: throw new IllegalStateException();
   180         }
   181 
   182         return new Rectangle(
   183             (column - 'A' + 1) * 50 + 25 - w, row * 50 + 25 - h, 2 * w, 2 * h
   184         );
   185     }
   186 
   187     private class MoveControl implements MoveProvider {
   188         final boolean horizontal;
   189 
   190         Point orig;
   191 
   192         private MoveControl(boolean horizontal) {
   193             this.horizontal = horizontal;
   194         }
   195         public void movementStarted(Widget widget) {
   196             System.err.println("started: " + widget.getBounds());
   197         }
   198 
   199         public void movementFinished(Widget widget) {
   200             try {
   201                 final Rectangle bounds = widget.getBounds();
   202                 final Move m = createMoveForDrop( bounds);
   203                 System.err.println("finish: " + m);
   204                 board = board.apply(m);
   205             } catch (IllegalPositionException ex) {
   206                 Exceptions.printStackTrace(ex);
   207             }
   208 
   209             view(scene, board);
   210         }
   211 
   212         public Point getOriginalLocation(Widget widget) {
   213             final Rectangle b = widget.getBounds();
   214             orig = new Point(b.x, b.y);
   215             try {
   216                 System.err.println("  where: " + createMoveForDrop(b));
   217             } catch (IllegalPositionException ex) {
   218                 Exceptions.printStackTrace(ex);
   219             }
   220             return orig;
   221         }
   222 
   223         public void setNewLocation(Widget widget, Point location) {
   224             final Rectangle b = new Rectangle(
   225                 round(location.x, true) + (horizontal ? 5 : 0),
   226                 round(location.y, false) + (horizontal ? 0 : 5),
   227                 horizontal ? 90 : 10,
   228                 horizontal ? 10 : 90
   229             );
   230             widget.setPreferredBounds(b);
   231             try {
   232                 System.err.println("move: " + createMoveForDrop(b));
   233             } catch (IllegalPositionException ex) {
   234                 System.err.println("no move");
   235             }
   236         }
   237 
   238         Move createMoveForDrop(final Rectangle bounds) throws IllegalPositionException {
   239             int column = bounds.x / 50;
   240             int row = bounds.y / 50;
   241             Orientation o = bounds.width > bounds.height ? Orientation.HORIZONTAL : Orientation.VERTICAL;
   242             switch (o) {
   243                 case HORIZONTAL: row--; break;
   244                 case VERTICAL: column--; break;
   245                 default: assert false;
   246             }
   247             if (column < 0) {
   248                 column = 0;
   249             }
   250             if (column >= 9) {
   251                 column = 8;
   252             }
   253             if (row < 0) {
   254                 row = 0;
   255             }
   256             if (row > 8) {
   257                 row = 8;
   258             }
   259             Move m = Move.fence((char) ('A' + column), 1 + row, o);
   260             return m;
   261         }
   262 
   263         int round(int p, boolean cmpHori) {
   264     //        p = horizontal ? orig.x + p: orig.y + p;
   265             int onboard = p / 50;
   266             if (onboard < 0) {
   267                 onboard = 0;
   268             }
   269             if (onboard >= 9) {
   270                 return p;
   271             }
   272             int real = 25 + onboard * 50;
   273             if (horizontal != cmpHori) {
   274                 return real - 5;
   275             } else {
   276                 return real;
   277             }
   278         }
   279     }
   280 
   281     private static final class PlayerWidget extends Widget {
   282         public PlayerWidget(Scene s) {
   283             super(s);
   284         }
   285 
   286         @Override
   287         protected Rectangle calculateClientArea() {
   288             return getBounds();
   289         }
   290 
   291         @Override
   292         protected void paintWidget() {
   293             Graphics2D g = getGraphics();
   294             Rectangle b = getBounds();
   295             g.drawOval(b.x + 5, b.y + 5, b.width - 10, b.height - 10);
   296         }
   297     }
   298 }