All Downloads are FREE. Search and download functionalities are using the official Maven repository.

codes.derive.foldem.tool.RangeMatrixBuilder Maven / Gradle / Ivy

/*
 * This file is part of Fold'em, a Java library for Texas Hold 'em Poker.
 *
 * Fold'em is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Fold'em is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Fold'em.  If not, see .
 */
package codes.derive.foldem.tool;

import static codes.derive.foldem.Poker.*;

import java.awt.Color;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.util.Collection;

import codes.derive.foldem.Hand;
import codes.derive.foldem.Range;

/**
 * A type that can generate images containing each hand in a range and its
 * respective weight in a matrix.
 */
public class RangeMatrixBuilder {
	
	/* Size of the hand matrix */
	private static final int MATRIX_SIZE = 13;
	
	/* The size in pixels (excluding 1px border) of output images. */
	private static final int SIZE_PX = 390;

	/* Card labels ordered by strength. */
	private static final char[] LABELS = {
		'A', 'K', 'Q', 'J', 'T', '9', '8', '7', '6', '5', '4', '3', '2'
	};
	
	/**
	 * Builds a matrix image using the specified {@link Range}.
	 * @param range
	 * 		The range to use.
	 * @return
	 * 		The image generated.
	 */
	public BufferedImage build(Range range) {

		/*
		 * Create an image to draw our matrix on.
		 */
		BufferedImage image = new BufferedImage(SIZE_PX + 1, SIZE_PX + 1,
				BufferedImage.TYPE_INT_ARGB);

		/*
		 * Obtain the Graphics2D context for our image.
		 */
		Graphics2D g = (Graphics2D) image.getGraphics();
		g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
				RenderingHints.VALUE_ANTIALIAS_ON);

		/*
		 * Begin rendering our matrix.
		 */
		int boxSize = SIZE_PX / MATRIX_SIZE;
		for (int x = 0; x < MATRIX_SIZE; x++) {
			int drawX = x * boxSize;
			for (int y = 0; y < MATRIX_SIZE; y++) {
				int drawY = y * boxSize;
				
				/*
				 * Obtain the label for the hand group at this coordinate,
				 */
				String label = label(x, y);

				/*
				 * Calculate the collective weight of hands at this location.
				 */
				Collection hands = handGroup(label);
				float weight = 0.0f;
				for (Hand hand : hands) {
					double w = 0.0;
					if (range.contains(hand)) {
						w = range.weight(hand);
					}
					weight += w / hands.size();
				}

				/*
				 * Calculate our color based on our collective weight.
				 */
				double wr = 2.0 * (1.0 - weight);
				double wg = 2.0 * weight;
				if (wg > 1.0) {
					wg = 1.0;
				}
				if (wr > 1.0) {
					wr = 1.0;
				}

				/*
				 * Set our box color.
				 */
				Color color = new Color((int) (255 * wr), (int) (255 * wg), 0);
				g.setColor(color);

				/*
				 * Calculate our box Y coordinate and height.
				 */
				int boxY = drawY + boxSize - (int) (boxSize * weight);
				int boxHeight = (int) (boxSize * weight);
				
				/*
				 * Draw the box foreground.
				 */
				g.fillRect(drawX, boxY, boxSize, boxHeight);

				/*
				 * Calculate the position of the label.
				 */
				FontMetrics metrics = g.getFontMetrics();
				int labelX = drawX + 1 + (boxSize - 1 - metrics.stringWidth(label)) / 2;
				int labelY = drawY + 1 + (boxSize - 1 + metrics.getMaxAscent()) / 2;
				
				/*
				 * Draw the label.
				 */
				g.setColor(Color.BLACK);
				g.drawString(label, labelX, labelY);
				
				/*
				 * Finally, render the outline for this group.
				 */
				g.drawRect(drawX, drawY, boxSize, boxSize);
			}
		}
		return image;
	}
	
	/**
	 * Finds the label to use at the specified coordinates of the matrix.
	 * @param x
	 * 		The x coordinate.
	 * @param y
	 * 		The y coordinate.
	 * @return
	 * 		The label to use at the specified coordinates.
	 */
	private static String label(int x, int y) {
		StringBuilder bldr = new StringBuilder();
		if (x < y) {
			bldr.append(LABELS[x]).append(LABELS[y]);
		} else {
			bldr.append(LABELS[y]).append(LABELS[x]);
		}
		if (x + y > x * 2) {
			bldr.append("o");
		} else if (x + y < x * 2) {
			bldr.append("s");
		}
		return bldr.toString();
	}
	
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy