Implement Duck Chess
authorH.G.Muller <hgm@hgm-xboard.(none)>
Thu, 20 Oct 2022 13:05:06 +0000 (15:05 +0200)
committerH.G.Muller <hgm@hgm-xboard.(none)>
Thu, 20 Oct 2022 13:11:25 +0000 (15:11 +0200)
An SVG image for a Duck is added. Communication with engine uses the
'Alien Edition' protocol, where a non-final leg is printed by the
engine on a separate line, suffixed by a comma. Peculiarity is that the
destination of the FIDE piece has to be written in place of the old
Duck location, and that the promotion suffix has to be on the final leg.
SAN writes the Duck destination behind the move, separated from it by a
comma. In this case the promotion suffix is on the first leg.

Makefile.am
backend.c
board.c
common.h
dialogs.c
draw.c
parser.c
svg/WhiteDucky.svg [new file with mode: 0644]

index a3051ba..4bea85d 100644 (file)
@@ -169,7 +169,7 @@ dist_svg_DATA = svg/icon_white.svg         svg/icon_black.svg      \
            svg/eo_Analyzing.svg     svg/eo_Black.svg          \
            svg/eo_Clear.svg         svg/eo_Ponder.svg         \
            svg/eo_Thinking.svg      svg/eo_Unknown.svg        \
-           svg/eo_White.svg
+           svg/eo_White.svg         svg/WhiteDucky.svg
 
 shogidir = $(gamedatadir)/themes/shogi
 dist_shogi_DATA = \
index 1b78234..c092efb 100644 (file)
--- a/backend.c
+++ b/backend.c
@@ -1273,6 +1273,7 @@ InitBackEnd1 ()
       case VariantLion:       /* should work */
       case VariantChuChess:   /* should work */
       case VariantJanggi:
+      case VariantDuck:
        break;
       }
     }
@@ -7083,7 +7084,7 @@ int lastLoadGameNumber = 0, lastLoadPositionNumber = 0;
 int lastLoadGameUseList = FALSE;
 char lastLoadGameTitle[MSG_SIZ], lastLoadPositionTitle[MSG_SIZ];
 ChessMove lastLoadGameStart = EndOfFile;
-int doubleClick;
+int doubleClick, doDuck = -1, duckX, duckY;
 Boolean addToBookFlag;
 static Board rightsBoard, nullBoard;
 
@@ -7091,7 +7092,7 @@ void
 UserMoveEvent (int fromX, int fromY, int toX, int toY, int promoChar)
 {
     ChessMove moveType;
-    ChessSquare pup;
+    ChessSquare pup = boards[currentMove][fromY][fromX];
     int ff=fromX, rf=fromY, ft=toX, rt=toY;
 
     /* Check if the user is playing in turn.  This is complicated because we
@@ -7139,14 +7140,14 @@ UserMoveEvent (int fromX, int fromY, int toX, int toY, int promoChar)
       case AnalyzeMode:
       case Training:
        if(fromY == DROP_RANK) break; // [HGM] drop moves (entered through move type-in) are automatically assigned to side-to-move
-       if ((int) boards[currentMove][fromY][fromX] >= (int) BlackPawn &&
-            (int) boards[currentMove][fromY][fromX] < (int) EmptySquare) {
+       if ((int) pup >= (int) BlackPawn &&
+            (int) pup < (int) EmptySquare) {
            /* User is moving for Black */
            if (WhiteOnMove(currentMove)) {
                DisplayMoveError(_("It is White's turn"));
                 return;
            }
-       } else {
+       } else if(pup < (int) BlackPawn) {
            /* User is moving for White */
            if (!WhiteOnMove(currentMove)) {
                DisplayMoveError(_("It is Black's turn"));
@@ -7384,6 +7385,17 @@ FinishMove (ChessMove moveType, int fromX, int fromY, int toX, int toY, int prom
 
   ClearMap();
 
+  if(gameInfo.variant == VariantDuck) {
+    if(doDuck < 0) { // Duck move not yet indicated
+      Board testBoard;
+      CopyBoard(testBoard, boards[forwardMostMove]); // do the move without Duck
+      ApplyMove(fromX, fromY, toX, toY, promoChar, testBoard);
+      DrawPosition(TRUE, testBoard);
+      duckX = fromX; duckY = fromY; doDuck = promoChar; // remember promotion
+      return 1;
+    }
+  }
+
   /* If we need the chess program but it's dead, restart it */
   ResurrectChessProgram();
 
@@ -7685,6 +7697,18 @@ LeftClick (ClickType clickType, int xPix, int yPix)
        x = BOARD_WIDTH - 1 - x;
     }
 
+    saveAnimate = appData.animate;
+    if(clickType == Press && doDuck >= 0) { // extra click for Duck placement
+       if(boards[currentMove][y][x] != EmptySquare && (x != duckX || y != duckY)) return; // ignore clicks on occupied square
+       killX = x; killY = y;
+       appData.animate = FALSE;
+       UserMoveEvent(duckX, duckY, toX, toY, doDuck); // promoChoice remembered in doDuck
+       fromX = fromY = killX = killY = -1;
+       appData.animate = saveAnimate;
+       doDuck = -1;
+       return;
+    }
+
     if(gameMode == EditPosition && fromX < 0 && selectedType != EmptySquare &&
        (boards[currentMove][y][x] == EmptySquare || x == createX && y == createY)) { // placement click
        if(clickType == Press) {
@@ -7950,7 +7974,6 @@ LeftClick (ClickType clickType, int xPix, int yPix)
 
     piece = boards[currentMove][fromY][fromX];
 
-    saveAnimate = appData.animate;
     if (clickType == Press) {
        if(gameInfo.variant == VariantChuChess && piece != WhitePawn && piece != BlackPawn) defaultPromoChoice = piece;
        if(gameMode == EditPosition && boards[currentMove][fromY][fromX] == EmptySquare) {
@@ -9120,9 +9143,13 @@ FakeBookMove: // [HGM] book: we jump here to simulate machine moves after book h
            if(q) legs = 2, p = q; else legs = 1;  // with 3-leg move we clipof first two legs!
            safeStrCpy(machineMove, firstLeg + (p - machineMove) + 1, 20);
        }
-       if(firstLeg[0]) { // there was a previous leg;
+       if(firstLeg[0]) { // there was a previous leg
+         char buf[20], *p = machineMove+1, *q = buf+1, f;
+         if(gameInfo.variant == VariantDuck) { // Duck Chess: 1st leg is FIDE move, 2nd is Duck
+           sscanf(machineMove, "%c%d%c%d", &f, &killY, &f, &killY); killX = f - AAA; killY -= ONE - '0';
+           safeStrCpy(machineMove, firstLeg, 20);
+          } else {
            // only support case where same piece makes two step
-           char buf[20], *p = machineMove+1, *q = buf+1, f;
            safeStrCpy(buf, machineMove, 20);
            while(isdigit(*q)) q++; // find start of to-square
            safeStrCpy(machineMove, firstLeg, 20);
@@ -9131,7 +9158,8 @@ FakeBookMove: // [HGM] book: we jump here to simulate machine moves after book h
            else if(*p == *buf)   // if first-leg to not equal to second-leg from first leg says unmodified (assume it is King move of castling)
            safeStrCpy(p, q, 20); // glue to-square of second leg to from-square of first, to process over-all move
            sscanf(buf, "%c%d", &f, &killY); killX = f - AAA; killY -= ONE - '0'; // pass intermediate square to MakeMove in global
-           firstLeg[0] = NULLCHAR; legs = 0;
+          }
+         firstLeg[0] = NULLCHAR; legs = 0;
        }
 
         if (!ParseOneMove(machineMove, forwardMostMove, &moveType,
@@ -10525,6 +10553,11 @@ ApplyMove (int fromX, int fromY, int toX, int toY, int promoChar, Board board)
 
       if( killX >= 0 && killY >= 0 ) { // [HGM] lion: Lion trampled over something
 //           victim = board[killY][killX],
+        if(gameInfo.variant == VariantDuck) { // killXY used to indicate Duck move
+           int r, f;
+           for(r=0; r<BOARD_HEIGHT; r++) for(f=BOARD_LEFT; f<BOARD_RGHT; f++) if(board[r][f] == DarkSquare) board[r][f] = EmptySquare;
+           board[killY][killX] = DarkSquare;
+        } else {
            killed = board[killY][killX],
            board[killY][killX] = EmptySquare,
            board[EP_STATUS] = EP_CAPTURE;
@@ -10532,6 +10565,7 @@ ApplyMove (int fromX, int fromY, int toX, int toY, int promoChar, Board board)
              killed2 = board[kill2Y][kill2X], board[kill2Y][kill2X] = EmptySquare;
            if(killed == EmptySquare) // [HGM] unload: kill-square also used for push destination
              board[killY][killX] = board[toY][toX], board[EP_STATUS] = EP_NONE;
+        }
       }
 
       if( board[toY][toX] != EmptySquare ) {
@@ -10889,17 +10923,24 @@ MakeMove (int fromX, int fromY, int toX, int toY, int promoChar)
 //    forwardMostMove++; // [HGM] bare: moved downstream
 
     diceRoll[0] = NULLCHAR; // [HGM] dice: consumed by this move
+  if(gameInfo.variant != VariantDuck) {
     if(kill2X >= 0) x = kill2X, y = kill2Y; else
     if(killX >= 0 && killY >= 0) x = killX, y = killY; // [HGM] lion: make SAN move to intermediate square, if there is one
+  }
     (void) CoordsToAlgebraic(boards[forwardMostMove],
                             PosFlags(forwardMostMove),
                             fromY, fromX, y, x, (killX < 0)*promoChar,
                             s);
     if(kill2X >= 0 && kill2Y >= 0)
         sprintf(s + strlen(s), "x%c%d", killX + AAA, killY + ONE - '0'); // 2nd leg of 3-leg move is always capture
-    if(killX >= 0 && killY >= 0)
+    if(killX >= 0 && killY >= 0) {
+        if(gameInfo.variant == VariantDuck) {
+          if(promoChar) sprintf(s + strlen(s), "=%c,%c%d", ToUpper(promoChar), killX + AAA, killY + ONE - '0');
+          else sprintf(s + strlen(s), ",%c%d", killX + AAA, killY + ONE - '0');
+        } else
         sprintf(s + strlen(s), "%c%c%d%c", p == EmptySquare || toX == fromX && toY == fromY || toX== kill2X && toY == kill2Y ? '-' : 'x',
                                            toX + AAA, toY + ONE - '0', promoChar);
+    }
 
     if(serverMoves != NULL) { /* [HGM] write moves on file for broadcasting (should be separate routine, really) */
         int timeLeft; static int lastLoadFlag=0; int king, piece;
diff --git a/board.c b/board.c
index c13082f..2c1f7bb 100644 (file)
--- a/board.c
+++ b/board.c
@@ -605,7 +605,7 @@ AnimateMove (Board board, int fromX, int fromY, int toX, int toY)
   if (piece >= EmptySquare) return;
 
   if(x2 >= 0) toX = kill2X, toY = kill2Y; else
-  if(killX >= 0) toX = killX, toY = killY; // [HGM] lion: first to kill square
+  if(killX >= 0 && gameInfo.variant != VariantDuck) toX = killX, toY = killY; // [HGM] lion: first to kill square
 
 again:
 
@@ -814,7 +814,7 @@ DrawSquare (int row, int column, ChessSquare piece, int do_flash)
        snprintf(tString, 3, "%d", piece);
        align = 4; // holdings count in upper-left corner
     }
-    if(piece == DarkSquare) square_color = 2;
+    if(piece == DarkSquare) square_color = (gameInfo.variant == VariantDuck ? 3 : 2);
     if(square_color == 2 || appData.blindfold) piece = EmptySquare;
 
     if (do_flash && piece != EmptySquare && appData.flashCount > 0) {
index 4dbb76a..ee516f4 100644 (file)
--- a/common.h
+++ b/common.h
@@ -415,6 +415,7 @@ typedef enum {
     VariantLion,
     VariantChuChess,
     VariantJanggi,
+    VariantDuck,
     VariantUnknown       /* Catchall for other unknown variants */
 } VariantClass;
 
@@ -466,6 +467,7 @@ typedef enum {
   "lion",\
   "elven",\
   "janggi",\
+  "duck",\
   "unknown" \
 }
 
index 731e423..753b331 100644 (file)
--- a/dialogs.c
+++ b/dialogs.c
@@ -498,7 +498,8 @@ static Option variantDescriptors[] = {
 { VariantJanggi, SAME_ROW, 135, NULL, (void*) &Pick, "#BFFFFF", NULL, Button, N_("Janggi (9x10)")}, // dummy, to have good alignment
 { VariantChuChess,      0, 135, NULL, (void*) &Pick, "#BFBFBF", NULL, Button, N_("elven chess (10x10)")},
 { VariantCourier, SAME_ROW,135, NULL, (void*) &Pick, "#BFFFBF", NULL, Button, N_("courier (12x8)")},
-{ -1,                   0, 135, NULL, (void*) &Pick, "#FFFFFF", NULL, Button, N_(" ")}, // dummy, to have good alignment
+{ VariantDuck,          0, 135, NULL, (void*) &Pick, "#FFFFFF", NULL, Button, N_("Duck Chess")},
+//{ -1,                   0, 135, NULL, (void*) &Pick, "#FFFFFF", NULL, Button, N_(" ")}, // dummy, to have good alignment
 { VariantChu,    SAME_ROW, 135, NULL, (void*) &Pick, "#BFFFBF", NULL, Button, N_("chu shogi (12x12)")},
 // optional buttons for engine-defined variants
 { 0, NO_OK, 0, NULL, NULL, "", NULL, EndMark , "" },
diff --git a/draw.c b/draw.c
index a05d41a..7d1792f 100644 (file)
--- a/draw.c
+++ b/draw.c
@@ -106,10 +106,10 @@ extern char *getenv();
 Boolean cairoAnimate;
 Option *currBoard;
 cairo_surface_t *csBoardWindow;
-static cairo_surface_t *pngPieceImages[2][(int)BlackPawn];   // png 256 x 256 images
-static cairo_surface_t *pngPieceBitmaps[2][(int)BlackPawn];  // scaled pieces as used
-static cairo_surface_t *pngPieceBitmaps2[2][(int)BlackPawn]; // scaled pieces in store
-static RsvgHandle *svgPieces[2][(int)BlackPawn]; // vector pieces in store
+static cairo_surface_t *pngPieceImages[2][(int)BlackPawn+1];   // png 256 x 256 images
+static cairo_surface_t *pngPieceBitmaps[2][(int)BlackPawn+1];  // scaled pieces as used
+static cairo_surface_t *pngPieceBitmaps2[2][(int)BlackPawn+1]; // scaled pieces in store
+static RsvgHandle *svgPieces[2][(int)BlackPawn+1]; // vector pieces in store
 static cairo_surface_t *pngBoardBitmap[2], *pngOriginalBoardBitmap[2];
 int useTexture, textureW[2], textureH[2];
 
@@ -165,7 +165,7 @@ SelectPieces(VariantClass v)
     int i;
     for(i=0; i<2; i++) {
        int p;
-       for(p=0; p<=(int)WhiteKing; p++)
+       for(p=0; p<=(int)WhiteKing+1; p++)
           pngPieceBitmaps[i][p] = pngPieceBitmaps2[i][p]; // defaults
        if(v == VariantShogi && BOARD_HEIGHT != 7) { // no exceptions in Tori Shogi
           pngPieceBitmaps[i][(int)WhiteCannon] = pngPieceBitmaps2[i][(int)WhiteTokin];
@@ -311,7 +311,7 @@ char *pngPieceNames[] = // must be in same order as internal piece encoding
   "LShield", "Pegasus", "Wizard", "Copper", "Iron", "Viking", "Flag", "Axe", "Dolphin", "Leopard", "Claw",
   "Left", "Butterfly", "PromoBishop", "PromoRook", "HCrown", "RShield", "Prince", "Phoenix", "Kylin", "Drunk", "Right",
   "GoldPawn", "GoldKnight", "PromoHorse", "PromoDragon", "GoldLance", "GoldSilver", "HSword", "PromoSword", "PromoHSword", "Princess", "King",
-  NULL
+  "Ducky", NULL
 };
 
 char *backupPiece[] = { // pieces that map on other in default theme ("Crown" - "Drunk")
@@ -494,6 +494,7 @@ CreatePNGPieces (char *pieceDir)
   int p;
   for(p=0; pngPieceNames[p]; p++) {
     ScaleOnePiece(0, p, pieceDir);
+    if(p == BlackPawn) break; // no black Duck
     ScaleOnePiece(1, p, pieceDir);
   }
   SelectPieces(gameInfo.variant);
@@ -791,6 +792,7 @@ BlankSquare (cairo_surface_t *dest, int x, int y, int color, ChessSquare piece,
          case 0: col = appData.darkSquareColor; break;
          case 1: col = appData.lightSquareColor; break;
          case 2: col = "#000000"; break;
+         case 3: col = "#6080C0"; break;
          default: col = "#808080"; break; // cannot happen
        }
        SetPen(cr, 2.0, col, 0);
@@ -821,6 +823,7 @@ pngDrawPiece (cairo_surface_t *dest, ChessSquare piece, int square_color, int x,
     }
     if(piece == WhiteKing && kind == appData.jewelled) piece = WhiteZebra;
     if(appData.upsideDown && flipView) kind = 1 - kind; // swap white and black pieces
+    if(square_color == 3) piece = BlackPawn, kind = 0; // Ducky
     BlankSquare(dest, x, y, square_color, piece, 1); // erase previous contents with background
     cr = cairo_create (dest);
     cairo_set_source_surface (cr, pngPieceBitmaps[kind][piece], x, y);
index 5246944..630a782 100644 (file)
--- a/parser.c
+++ b/parser.c
@@ -523,6 +523,13 @@ NextUnit (char **p)
                fromY = (currentMoveString[1] = coord[1] + '0') - ONE;
                currentMoveString[4] = cl.promoCharIn = PromoSuffix(p);
                currentMoveString[5] = NULLCHAR;
+               if(**p == ',' && gameInfo.variant == VariantDuck) { // Duck square follows
+                   currentMoveString[7] = currentMoveString[4];
+                   currentMoveString[4] = ';';
+                   currentMoveString[5] = *++*p; killX = **p - AAA;
+                   currentMoveString[6] = *++*p; killY = *(*p)++ - ONE;
+                   currentMoveString[8] = NULLCHAR;
+               }
                if(**p == 'x' && !cl.promoCharIn) { // other leg follows
                    char *q = *p;
                    int x = *++*p, y;
diff --git a/svg/WhiteDucky.svg b/svg/WhiteDucky.svg
new file mode 100644 (file)
index 0000000..4f3866a
--- /dev/null
@@ -0,0 +1,224 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   id="svg2"
+   version="1.1"
+   inkscape:version="0.47 r22583"
+   width="100"
+   height="100"
+   sodipodi:docname="WhiteDuck.svg">
+  <metadata
+     id="metadata8">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <defs
+     id="defs6">
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       id="perspective10" />
+    <inkscape:perspective
+       id="perspective3614"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective3638"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective3638-9"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective3638-0"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective3638-96"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective3638-1"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective3638-19"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective3625"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective3647"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective3669"
+       inkscape:persp3d-origin="0.5 : 0.33333333 : 1"
+       inkscape:vp_z="1 : 0.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 0.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+  </defs>
+  <sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="1124"
+     inkscape:window-height="802"
+     id="namedview4"
+     showgrid="false"
+     inkscape:zoom="2"
+     inkscape:cx="193"
+     inkscape:cy="94"
+     inkscape:window-x="0"
+     inkscape:window-y="24"
+     inkscape:window-maximized="0"
+     inkscape:current-layer="svg2" />
+  <g
+     id="g3637">
+    <g
+       id="g3616">
+      <path
+         sodipodi:type="arc"
+         style="color:#000000;fill:none;stroke:#a2b1fa;stroke-width:3.59820843000000012;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+         id="path3613"
+         sodipodi:cx="199.25"
+         sodipodi:cy="202.5"
+         sodipodi:rx="32.75"
+         sodipodi:ry="10"
+         d="m 232,202.5 a 32.75,10 0 1 1 -65.5,0 32.75,10 0 1 1 65.5,0 z"
+         transform="matrix(1.0050764,0,0,0.69162518,-149.51147,-59.804098)" />
+      <path
+         sodipodi:type="arc"
+         style="color:#000000;fill:none;stroke:#a2b1fa;stroke-width:2.31191682999999992;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+         id="path3613-4"
+         sodipodi:cx="199.25"
+         sodipodi:cy="202.5"
+         sodipodi:rx="32.75"
+         sodipodi:ry="10"
+         d="m 232,202.5 a 32.75,10 0 1 1 -65.5,0 32.75,10 0 1 1 65.5,0 z"
+         transform="matrix(1.3922046,0,0,1.2094699,-225.89676,-164.41765)" />
+      <path
+         sodipodi:type="arc"
+         style="color:#000000;fill:none;stroke:#a2b1fa;stroke-width:1.72233140000000007;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+         id="path3613-4-7"
+         sodipodi:cx="199.25"
+         sodipodi:cy="202.5"
+         sodipodi:rx="32.75"
+         sodipodi:ry="10"
+         d="m 232,202.5 a 32.75,10 0 1 1 -65.5,0 32.75,10 0 1 1 65.5,0 z"
+         transform="matrix(1.7505717,0,0,1.7331222,-298.05141,-269.70724)" />
+    </g>
+    <g
+       id="g3628">
+      <path
+         style="fill:#f5e016;fill-opacity:1;stroke:#000000;stroke-width:2.20000004999999987;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+         d="M 50.10422,39.31099 C 62.98639,22.18929 46.67998,9.48478 37.17546,9.49568 25.28834,10.88793 19.86873,16.72659 19.23351,25.85452 c 5.37616,0.31504 8.87072,1.88449 10.02638,5.01319 -0.52127,4.44955 -3.00742,6.44301 -6.33245,7.38787 l 3.43008,3.95778 c -4.63103,3.8642 -8.32649,9.2487 -7.38786,22.16359 2.9658,12.66059 12.61804,15.59547 23.21899,17.15039 14.34165,1.81151 25.5867,-1.0219 34.3008,-7.65171 12.80354,-11.42796 12.49244,-39.20106 9.48962,-36.66517 -4.92718,4.16103 -30.64579,7.08709 -35.611,1.83667"
+         id="path2822"
+         sodipodi:nodetypes="cccccccccsc" />
+      <path
+         style="fill:none;stroke:#000000;stroke-width:2.20000005;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+         d="m 43.50792,63.58539 c 9.78278,3.05149 19.79904,4.7799 31.66226,-3.95778 4.65312,-3.3093 5.15886,-7.14208 -2.90237,-5.01319 3.6299,-1.42009 2.71518,-7.76065 -3.95778,-3.69394 3.05525,-4.93585 -1.51841,-7.69981 -14.24802,-2.11081 l 0,0"
+         id="path2824"
+         sodipodi:nodetypes="cccccc" />
+      <path
+         style="fill:#e38100;fill-opacity:1;stroke:#000000;stroke-width:2.20000005;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+         d="m 19.23351,26.38223 c 6.01739,0.15753 8.15356,2.25567 10.02638,4.48548 -1.23478,6.59234 -6.84509,8.18408 -12.92876,9.23483 -4.74654,-0.61705 -8.97975,-1.75462 -6.86015,-5.80475 l 7.38786,-5.54089 2.37467,-2.37467 z"
+         id="path2826"
+         sodipodi:nodetypes="cccccc" />
+      <path
+         sodipodi:type="arc"
+         style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:8.3380003;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+         id="path2828"
+         sodipodi:cx="140.5"
+         sodipodi:cy="88.5"
+         sodipodi:rx="13.5"
+         sodipodi:ry="13.5"
+         d="m 154,88.5 a 13.5,13.5 0 1 1 -27,0 13.5,13.5 0 1 1 27,0 z"
+         transform="matrix(0.26385224,0,0,0.26385224,-1.61082,2.89938)" />
+      <path
+         sodipodi:type="arc"
+         style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:#ffffcc;stroke-width:8.3380003;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+         id="path3602"
+         sodipodi:cx="141"
+         sodipodi:cy="83.5"
+         sodipodi:rx="4"
+         sodipodi:ry="5.5"
+         d="m 145,83.5 a 4,5.5 0 1 1 -8,0 4,5.5 0 1 1 8,0 z"
+         transform="matrix(0.26385224,0,0,0.26385224,-1.61082,2.89938)" />
+      <path
+         sodipodi:type="arc"
+         style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:8.3380003;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+         id="path3604"
+         sodipodi:cx="51.5"
+         sodipodi:cy="123.5"
+         sodipodi:rx="2.5"
+         sodipodi:ry="2.5"
+         d="m 54,123.5 a 2.5,2.5 0 1 1 -5,0 2.5,2.5 0 1 1 5,0 z"
+         transform="matrix(0.26385224,0,0,0.26385224,1.81926,4.48249)" />
+      <path
+         sodipodi:type="arc"
+         style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#000000;stroke-width:8.3380003;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
+         id="path3604-2"
+         sodipodi:cx="51.5"
+         sodipodi:cy="123.5"
+         sodipodi:rx="2.5"
+         sodipodi:ry="2.5"
+         d="m 54,123.5 a 2.5,2.5 0 1 1 -5,0 2.5,2.5 0 1 1 5,0 z"
+         transform="matrix(0.26385224,0,0,0.26385224,-2.5343,2.76745)" />
+    </g>
+  </g>
+</svg>