/** * 指定したサイズ、置石で棋譜の{@link RootGameTree}を作成します。 * * @param sgfSize 碁盤の大きさ * @param handicap 置石の数(0:互先, 1:定先、2:二子…) * @return 作成した棋譜。NOT NULL * @throws org.unitarou.lang.NullArgumentException 引数が <code>null</code>の場合 * @throws IllegalArgumentException sgfSizeが正方形以外でnumberが2以上の場合 */ public static RootGameTree createGame(SgfSize sgfSize, Handicap handicap) { ArgumentChecker.throwIfNull(sgfSize, handicap); RootGameTree rgt = new RootGameTree(); rgt.setSize(sgfSize); rgt.setFileFormat(FileFormat.VERSION_4); rgt.setCharset(new SgfCharset(Charset.defaultCharset())); rgt.setGameMode(GameMode.IGO); rgt.setGameType(GameType.GAME); rgt.setStyle(Style.SIBLINGS_SHOW_VAL); Node node = rgt.getSequence().getFirst(); node.addProperty(SgfId.HANDICAP.makeProperty(handicap)); node.addProperty( SgfId.PLAYER_TO_PLAY.makeProperty( (1 < handicap.getIntValue()) ? SgfColor.WHITE : SgfColor.BLACK)); Set<SgfPoint> handicappedStones = composeHandicapStone(sgfSize, handicap); if (!handicappedStones.isEmpty()) { node.addProperty(SgfId.ADD_BLACK.makeProperty(handicappedStones)); } return rgt; }
/** * 引数の条件に合致した置き石を返します。 * * @param sgfSize * @param handicap * @throws IllegalArgumentException sgfSizeが正方形以外でnumberが2以上の場合 * @return 置き石の座標。NOT NULL */ private static Set<SgfPoint> composeHandicapStone(SgfSize sgfSize, Handicap handicap) { int hd = handicap.getIntValue(); if (hd < 2) { return Collections.emptySet(); } if (sgfSize.width() != sgfSize.height()) { throw new IllegalArgumentException(); } Set<SgfPoint> pointSet = new HashSet<SgfPoint>(9); final int size = sgfSize.width(); int left = size + 1, middle = size + 1, right = size + 1; if (size < 9) { left = size / 5 + 1; right = size - left + 1; middle = size / 2 + 1; } else if (size < 13) { left = 3; right = size - left + 1; middle = size / 2 + 1; } else { left = 4; right = size - left + 1; middle = size / 2 + 1; } switch (hd) { case 9: pointSet.add(SgfPoint.create(sgfSize, middle, left)); pointSet.add(SgfPoint.create(sgfSize, middle, right)); case 7: pointSet.add(SgfPoint.create(sgfSize, right, middle)); pointSet.add(SgfPoint.create(sgfSize, left, middle)); case 5: pointSet.add(SgfPoint.create(sgfSize, middle, middle)); case 4: pointSet.add(SgfPoint.create(sgfSize, right, right)); case 3: pointSet.add(SgfPoint.create(sgfSize, left, left)); case 2: pointSet.add(SgfPoint.create(sgfSize, right, left)); pointSet.add(SgfPoint.create(sgfSize, left, right)); break; case 8: pointSet.add(SgfPoint.create(sgfSize, middle, left)); pointSet.add(SgfPoint.create(sgfSize, middle, right)); case 6: pointSet.add(SgfPoint.create(sgfSize, right, middle)); pointSet.add(SgfPoint.create(sgfSize, left, middle)); pointSet.add(SgfPoint.create(sgfSize, right, right)); pointSet.add(SgfPoint.create(sgfSize, left, left)); pointSet.add(SgfPoint.create(sgfSize, right, left)); pointSet.add(SgfPoint.create(sgfSize, left, right)); } return pointSet; }