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