Commit 6d3312f3 authored by panlabmcw's avatar panlabmcw
Browse files

test

parent 54563d80
No related merge requests found
Pipeline #82601 failed with stage
Showing with 1184 additions and 2 deletions
+1184 -2
package edu.caltech.cs2.datastructures;
import edu.caltech.cs2.interfaces.IDeque;
import edu.caltech.cs2.interfaces.IQueue;
import edu.caltech.cs2.interfaces.IStack;
import java.util.Iterator;
public class ArrayDeque<E> implements IDeque<E>, IQueue<E>, IStack<E> {
private E[] data;
private int size;
private static final int DEFAULT_CAPACITY = 10;
private static final int DEFAULT_GROWTH = 2;
public ArrayDeque() {
this(DEFAULT_CAPACITY);
}
public ArrayDeque(int initialCapacity) {
this.data = (E[]) new Object[initialCapacity];
this.size = 0;
}
@Override
public void addFront(E e) {
resize();
if (this.size > 0) {
System.arraycopy(this.data, 0, this.data, 1, this.size);
}
this.data[0] = e;
this.size++;
}
@Override
public void addBack(E e) {
resize();
this.data[this.size] = e;
this.size++;
}
@Override
public E removeFront() {
resize();
if (this.size == 0){
return null;
}
E e = this.data[0];
System.arraycopy(this.data, 1, this.data, 0, this.size - 1);
this.size--;
return e;
}
@Override
public E removeBack() {
resize();
if (this.size == 0){
return null;
}
E e = this.data[this.size - 1];
this.size--;
return e;
}
@Override
public boolean enqueue(E e) {
addFront(e);
return true;
}
@Override
public E dequeue() {
if (this.data[0] == null){
return null;
} else {
return removeBack();
}
}
@Override
public boolean push(E e) {
addBack(e);
return true;
}
@Override
public E pop() {
if (this.data[0] == null){
return null;
} else {
return removeBack();
}
}
@Override
public E peekFront() {
if (this.size == 0){
return null;
}
return this.data[0];
}
@Override
public E peekBack() {
if (this.size == 0){
return null;
}
return this.data[this.size - 1];
}
@Override
public E peek() {
return peekBack();
}
@Override
public Iterator<E> iterator() {
return new ArrayDequeIterator();
}
@Override
public int size() {
return this.size;
}
private class ArrayDequeIterator implements Iterator<E> {
private int idx = 0;
@Override
public boolean hasNext() {
return this.idx < ArrayDeque.this.size;
}
@Override
public E next() {
E element = ArrayDeque.this.data[this.idx];
this.idx++;
return element;
}
}
// from lecture notes
private void resize() {
if (this.size == this.data.length) {
E[] newData = (E[])new Object[this.data.length * DEFAULT_GROWTH];
System.arraycopy(this.data, 0, newData, 0, this.size);
this.data = newData;
}
}
@Override
public String toString() {
if (this.size == 0) {
return "[]";
}
else {
StringBuilder resultSB = new StringBuilder();
resultSB.append("[");
for (int i = 0; i < this.size; i++) {
resultSB.append(this.data[i]).append(", ");
}
String result = resultSB.toString();
result = result.substring(0, result.length() - 2);
return result + "]";
}
}
}
package edu.caltech.cs2.datastructures;
import edu.caltech.cs2.interfaces.ICollection;
import edu.caltech.cs2.interfaces.IDictionary;
import java.util.Iterator;
import java.util.function.Supplier;
public class ChainingHashDictionary<K, V> implements IDictionary<K, V> {
// chain, supplier<idict>
//int size, capacity, double load factor (1)
//array of dictionary data
private Supplier<IDictionary<K, V>> chain;
private IDictionary<K,V>[] data;
private double loadFactor = 1.0;
private int size;
private int capacity = 17;
public ChainingHashDictionary(Supplier<IDictionary<K, V>> chain) {
this.chain = chain;
this.data = new IDictionary[capacity];
this.size = 0;
for (int i = 0; i < data.length; i++){
this.data[i] = chain.get();
}
}
/**
* @param key
* @return value corresponding to key
*/
@Override
public V get(K key) {
// V val = this.data[index].get(key);
IDictionary<K,V> chain = this.data[Math.abs((key.hashCode() % capacity + capacity) % capacity)];
if (chain == null || key == null) {
return null;
}
return chain.get(key);
}
@Override
public V remove(K key) {
int index = (key.hashCode() % capacity + capacity) % capacity;
IDictionary<K,V> chain = this.data[index];
V val = chain.remove(key);
if (val == null) {
return null;
} else {
this.size--;
this.data[index] = chain;
}
return val;
}
@Override
public V put(K key, V value) {
if (this.size/this.data.length > this.loadFactor) {
rehash();
}
V val = null;
int index = Math.abs((key.hashCode() % capacity + capacity) % capacity);
IDictionary<K,V> chain = this.data[index];
if (chain == null) {
chain = this.chain.get();
}
if (chain.get(key) != null) {
val = chain.get(key);
} else {
this.size++;
}
this.data[index] = chain;
chain.put(key, value);
return val;
}
public void rehash(){
//make bigger array
//copy items over
//this.data = new Arr
IDictionary<K,V>[] arr = new IDictionary[(this.data.length * 2) + 1];
for (IDictionary<K,V> chain : this.data){
if (chain != null) {
for (K key : chain.keys()) {
int idx = Math.abs((key.hashCode() % arr.length + arr.length) % arr.length);
IDictionary<K, V> data = arr[idx];
if (data == null) {
data = this.chain.get();
}
arr[idx] = data;
data.put(key, chain.get(key));
}
}
}
this.data = arr;
this.capacity = arr.length;
}
@Override
public boolean containsKey(K key) {
return (this.get(key) != null);
}
/**
* @param value
* @return true if the HashDictionary contains a key-value pair with
* this value, and false otherwise
*/
@Override
public boolean containsValue(V value) {
return this.values().contains(value);
}
/**
* @return number of key-value pairs in the HashDictionary
*/
@Override
public int size() {
return this.size;
}
@Override
public ICollection<K> keys() {
ICollection<K> keys = new ArrayDeque<>();
for (IDictionary<K,V> dict : this.data){
if (dict != null) {
for (K key : dict.keys()) {
keys.add(key);
}
}
}
return keys;
}
@Override
public ICollection<V> values() {
ICollection<V> values = new ArrayDeque<>();
for (IDictionary<K, V> dict: this.data){
if (dict != null) {
for (V value : dict.values()) {
values.add(value);
}
}
}
return values;
}
/**
* @return An iterator for all entries in the HashDictionary
*/
@Override
public Iterator<K> iterator() {
return this.keys().iterator();
}
}
package edu.caltech.cs2.datastructures;
import edu.caltech.cs2.interfaces.IDeque;
import edu.caltech.cs2.interfaces.IQueue;
import edu.caltech.cs2.interfaces.IStack;
import java.util.Iterator;
public class LinkedDeque<E> implements IDeque<E>, IQueue<E>, IStack<E> {
private Node<E> head;
private int size;
private Node<E> tail;
public LinkedDeque(){
this.head = null;
this.tail = null;
this.size = 0;
}
private static class Node<E> {
public final E data;
public Node<E> next;
public Node<E> prev;
public Node(E data) {
this(data, null, null);
}
public Node(E data, Node<E> next, Node<E> prev) {
this.data = data;
this.next = next;
this.prev = prev;
}
}
@Override
public void addFront(E e) {
if (this.size == 0){
Node<E> tempNode = new Node<>(e);
this.tail = tempNode;
this.head = tempNode;
} else {
Node<E> tempHead = new Node<>(e, this.head, null);
// previous is this head
this.head.prev = tempHead;
//switch node
this.head = tempHead;
}
this.size++;
}
@Override
public void addBack(E e) {
if (this.size == 0){
this.head = new Node<>(e);
this.tail = this.head;
} else {
Node<E> tempTail = new Node<>(e, null, this.tail);
this.tail.next = tempTail;
this.tail = tempTail;
}
this.size++;
}
@Override
public E removeFront() {
if (this.size == 0) {
return null;
}
E tempHead = this.head.data;
this.head = this.head.next;
if (this.head != null) {
this.head.prev = null;
}
this.size--;
if (this.size == 0) {
this.tail = this.head;
}
return tempHead;
}
@Override
public E removeBack() {
if (this.size == 0) {
return null;
}
E tempHead = this.tail.data;
this.tail = this.tail.prev;
if (this.tail != null) {
this.tail.next = null;
}
this.size--;
if (this.size == 0) {
this.head = this.tail;
}
return tempHead;
}
@Override
public boolean enqueue(E e) {
addFront(e);
return true;
}
@Override
public E dequeue() {
if (this.head == null || this.tail == null){
return null;
} else {
return removeBack();
}
}
@Override
public boolean push(E e) {
addBack(e);
return true;
}
@Override
public E pop() {
if (this.head == null || this.tail == null){
return null;
} else {
return removeBack();
}
}
@Override
public E peekFront() {
if (this.size == 0){
return null;
}
return this.head.data;
}
@Override
public E peekBack() {
if (this.size == 0) {
return null;
}
return this.tail.data;
}
@Override
public E peek() {
return peekBack();
}
@Override
public Iterator<E> iterator() {
return new LinkedDequeIterator();
}
@Override
public int size() {
return this.size;
}
@Override
public String toString(){
String returnStatement = "";
if (this.size == 0) {
return "[]";
}
else {
returnStatement += "[";
Node<E> tempNode = this.head;
for (int i = 0; i < this.size; i++){
returnStatement += tempNode.data.toString();
returnStatement += ", ";
tempNode = tempNode.next;
}
returnStatement = returnStatement.substring(0, returnStatement.length() - 2);
returnStatement += "]";
return returnStatement;
}
}
private class LinkedDequeIterator implements Iterator<E> {
private Node<E> currNode = null;
public LinkedDequeIterator(){
this.currNode = LinkedDeque.this.head;
}
@Override
public boolean hasNext() {
return this.currNode != null;
}
@Override
public E next() {
E element = currNode.data;
this.currNode = currNode.next;
return element;
}
}
}
package edu.caltech.cs2.datastructures;
import edu.caltech.cs2.interfaces.IDictionary;
import edu.caltech.cs2.interfaces.IPriorityQueue;
import java.util.Iterator;
public class MinFourHeap<E> implements IPriorityQueue<E> {
private static final int DEFAULT_CAPACITY = 10;
private static final int GROWTH_FACTOR = 2;
private int size;
private PQElement<E>[] data;
private IDictionary<E, Integer> keyToIndexMap;
/**
* Creates a new empty heap with DEFAULT_CAPACITY.
*/
public MinFourHeap() {
this.size = 0;
this.data = new PQElement[DEFAULT_CAPACITY];
this.keyToIndexMap = new ChainingHashDictionary<>(MoveToFrontDictionary::new);
}
@Override
public void increaseKey(PQElement<E> key) {
if (!this.keyToIndexMap.containsKey(key.data)) {
throw new IllegalArgumentException("Can't modify a nonexistent element!");
}
if (key.priority > this.data[this.keyToIndexMap.get(key.data)].priority) {
this.data[this.keyToIndexMap.get(key.data)] = key;
percDown(this.keyToIndexMap.get(key.data));
}
}
@Override
public void decreaseKey(PQElement<E> key) {
if (!this.keyToIndexMap.containsKey(key.data)) {
throw new IllegalArgumentException("Can't modify a nonexistent element!");
}
else if (key.priority < this.data[this.keyToIndexMap.get(key.data)].priority) {
this.data[this.keyToIndexMap.get(key.data)] = key;
percUp(this.keyToIndexMap.get(key.data));
}
}
@Override
public boolean enqueue(PQElement<E> epqElement) {
if (this.keyToIndexMap.containsKey(epqElement.data)) {
throw new IllegalArgumentException("This key is already in MinFourHeap!");
}
else if (this.size >= this.data.length) {
PQElement<E>[] temp = new PQElement[this.size * GROWTH_FACTOR];
System.arraycopy(this.data, 0, temp, 0, this.size);
this.data = temp;
}
this.data[this.size] = epqElement;
this.keyToIndexMap.put(epqElement.data, this.size);
this.size++;
percUp(this.size - 1);
return true;
}
@Override
public PQElement<E> dequeue() {
if (this.size == 0) {
return null;
}
else if (this.size == 1) {
PQElement<E> root = this.data[0];
this.size--;
this.keyToIndexMap.remove(root.data);
this.data[0] = null;
return root;
}
PQElement<E> root = this.data[0];
this.size--;
this.keyToIndexMap.remove(root.data);
this.data[0] = this.data[this.size];
this.keyToIndexMap.put(this.data[0].data, 0);
percDown(0);
return root;
}
@Override
public PQElement<E> peek() {
if (this.size == 0) {
throw new IllegalArgumentException("Empty array, nothing to peek!");
}
return data[0];
}
@Override
public int size() {
return this.size;
}
@Override
public Iterator<PQElement<E>> iterator() {
return null;
}
private boolean hasChild (int index, int childNum) {
int childIndex = ((4 * index) + childNum);
return (childIndex < this.size && childIndex > 0);
}
private void percUp(int idx) {
while ((idx - 1) / 4 >= 0 && this.data[(idx - 1) / 4].priority > this.data[idx].priority) {
int parentidx = (idx - 1) / 4;
PQElement temp = data[parentidx];
data[parentidx] = data[idx];
data[idx] = temp;
int temp2 = this.keyToIndexMap.get(data[parentidx].data);
this.keyToIndexMap.put(data[parentidx].data, this.keyToIndexMap.get(data[idx].data));
this.keyToIndexMap.put(data[idx].data, temp2);
idx = (idx - 1) / 4;;
}
}
private void percDown(int idx) {
while (hasChild(idx, 1)) {
int parentidx = 0;
int minchildIndex = ((4 * idx) + 1);
if (minchildIndex >= this.size) {
minchildIndex = 1;
}
double min = this.data[minchildIndex].priority;
int minChildIndex = minchildIndex;
int childNum = 2;
while (hasChild(idx, childNum) && childNum <= 4) {
int childIndex = ((4 * idx) + childNum);
if(this.data[childIndex].priority < min) {
min = this.data[childIndex].priority;
minChildIndex = childIndex;
}
childNum++;
}
parentidx = minChildIndex;
PQElement smallestChild = this.data[parentidx];
if (smallestChild.priority < this.data[idx].priority) {
PQElement temp = data[parentidx];
data[parentidx] = data[idx];
data[idx] = temp;
int temp2 = this.keyToIndexMap.get(data[parentidx].data);
this.keyToIndexMap.put(data[parentidx].data, this.keyToIndexMap.get(data[idx].data));
this.keyToIndexMap.put(data[idx].data, temp2);
} else {
break;
}
idx = parentidx;
}
}
}
\ No newline at end of file
package edu.caltech.cs2.datastructures;
import edu.caltech.cs2.interfaces.ICollection;
import edu.caltech.cs2.interfaces.IDictionary;
import java.util.Iterator;
public class MoveToFrontDictionary<K, V> implements IDictionary<K,V> {
//keep track global head <Node <K, V>
//dictionary nodes have K key, V value
//Node<K,V> next
private Node<K, V> head;
private int size;
public MoveToFrontDictionary() {
this.head = null;
this.size = 0;
}
private static class Node<K, V> {
public K key;
public V value;
public Node<K, V> next;
public Node(K key, V value) {
this(key, value, null);
}
public Node(K key, V value, Node<K, V> next){
this.key = key;
this.value = value;
this.next = next;
}
}
@Override
public V remove(K key) {
//call get() on key
//head = head.next
if (this.head == null){
return null;
}
if (!this.containsKey(key)){
return null;
}
if (this.head.key.equals(key)){
V value = this.head.value;
this.head = this.head.next;
this.size --;
return value;
}
Node<K, V> current = this.head;
Node<K, V> prev = null;
while (current != null && !current.key.equals(key)){
prev = current;
current = current.next;
}
if (current == null) {
return null;
}
prev.next = current.next;
this.size--;
return current.value;
}
@Override
public V put(K key, V value) {
//save head node as oldHead
//Head = new Node(key, val)
//head.next = old.head (???)
V oldHead = this.remove(key);
Node<K, V> node = new Node<K, V>(key, value);
if (this.head != null){
node.next = this.head;
}
this.head = node;
this.size++;
return oldHead;
}
@Override
public boolean containsKey(K key) {
return this.keys().contains(key);
}
@Override
public boolean containsValue(V value) {
return this.values().contains(value);
}
@Override
public int size() {
return this.size;
}
@Override
public ICollection<K> keys() {
ICollection<K> deq = new ArrayDeque<>();
if (this.head == null) {
return deq;
}
Node<K, V> current = this.head;
while (current != null) {
deq.add(current.key);
current = current.next;
}
return deq;
}
@Override
public ICollection<V> values() {
ICollection<V> deq = new ArrayDeque<>();
if (this.head == null){
return deq;
}
Node<K, V> current = this.head;
while (current != null) {
deq.add(current.value);
current = current.next;
}
return deq;
}
public V get(K key) {
if (this.head == key){
return this.head.value;
}
else {
Node<K, V> curr = this.head;
while (curr != null) {
if (curr.key.equals(key)){
V val = curr.value;
/*
//rather than use put, directly change the pointers of the node being accessed
Node<K, V> nxtNode = curr.next;
nxtNode.next = this.head;
this.head = nxtNode;
//previous node
//create a new node at front of list with the node that is being accessed
*/
this.put(key, val);
return val;
}
curr = curr.next;
}
}
return null;
}
@Override
public Iterator<K> iterator() {
return new MoveToFrontIterator(this);
}
private class MoveToFrontIterator implements Iterator<K>{
//take linkeddeque iterator
private Node<K, V> currNode = null;
public MoveToFrontIterator(MoveToFrontDictionary dict){
this.currNode = dict.head;
}
@Override
public boolean hasNext() {
return this.currNode != null;
}
@Override
public K next() {
K element = currNode.key;
this.currNode = currNode.next;
return element;
}
}
}
package edu.caltech.cs2.interfaces;
import edu.caltech.cs2.datastructures.LinkedDeque;
public interface IDictionary<K, V> extends Iterable<K> {
public static class Entry<K, V> {
public final K key;
public V value;
public Entry(K key) {
this(key, null);
}
public Entry(K key, V value) {
this.key = key;
this.value = value;
}
}
/**
* Returns the value to which the specified key is mapped,
* or {@code null} if this map contains no mapping for the key.
*/
public V get(K key);
/**
* Removes the mapping for the specified key from this map if present.
*
* @param key key whose mapping is to be removed from the map
* @return the previous value associated with {@code key}, or
* {@code null} if there was no mapping for {@code key}.
*/
public V remove(K key);
/**
* Associates the specified value with the specified key in this map.
* If the map previously contained a mapping for the key, the old
* value is replaced.
*
* @param key key with which the specified value is to be associated
* @param value value to be associated with the specified key
* @return the previous value associated with {@code key}, or
* {@code null} if there was no mapping for {@code key}.
*/
public V put(K key, V value);
/**
* Returns {@code true} if this map contains a mapping for the
* specified key.
*
* @param key The key whose presence in this map is to be tested
* @return {@code true} if this map contains a mapping for the specified
* key.
*/
public boolean containsKey(K key);
/**
* Returns {@code true} if this map maps one or more keys to the
* specified value.
*
* @param value value whose presence in this map is to be tested
* @return {@code true} if this map maps one or more keys to the
* specified value
*/
public boolean containsValue(V value);
/**
* Returns the number of key-value mappings in this map.
*
* @return the number of key-value mappings in this map
*/
public int size();
/**
* Returns {@code true} if this map contains no key-value mappings.
*
* @return {@code true} if this map contains no key-value mappings
*/
default public boolean isEmpty() {
return this.size() == 0;
}
/**
* Returns a {@link ICollection} of the keys contained in this map.
*
* @return a collection of the keys contained in this map
*/
public ICollection<K> keys();
/**
* Returns a {@link ICollection} of the values contained in this map
* which does not contain duplicates.
*
* @return a collection of the values contained in this map
*/
public ICollection<V> values();
default public ICollection<Entry<K, V>> entrySet() {
IDeque<Entry<K, V>> entries = new LinkedDeque<>();
for (K key : keys()) {
entries.add(new Entry(key, this.get(key)));
}
return entries;
}
@SuppressWarnings("unchecked cast")
default ISet<K> keySet() {
return ISet.getBackingSet((IDictionary<K, Object>)this);
}
}
package edu.caltech.cs2.interfaces;
/**
* This interface represents a Priority Queue - a data structure that is very similar to a queue but
* stores values in ascending order.
* @param <E> Element type
*/
public interface IPriorityQueue<E> extends IQueue<IPriorityQueue.PQElement<E>> {
public static class PQElement<E> {
public final E data;
public final double priority;
public PQElement(E data, double priority) {
this.data = data;
this.priority = priority;
}
@Override
public int hashCode() {
return this.data.hashCode();
}
@Override
public boolean equals(Object o) {
if (!(o instanceof PQElement)) {
return false;
}
return this.data.equals(((PQElement)o).data);
}
@Override
public String toString() {
return "(" + this.data + ", " + this.priority + ")";
}
}
/**
* Increase the priority of the key at idx
* @param key - the new key with the new priority
*/
public void increaseKey(PQElement<E> key);
/**
* Decrease the priority of the key at idx
* @param key - the new key with the new priority
*/
public void decreaseKey(PQElement<E> key);
}
\ No newline at end of file
package edu.caltech.cs2.interfaces;
import java.util.Iterator;
public class ISet<E> implements Iterable<E> {
private IDictionary<E, Object> internalDictionary;
protected ISet(IDictionary<E, Object> dict) {
this.internalDictionary = dict;
}
public static <E> ISet<E> getBackingSet(IDictionary<E, Object> dict) {
return new ISet<E>(dict);
}
/**
* Returns the number of elements in this set (its cardinality). If this
* set contains more than {@code Integer.MAX_VALUE} elements, returns
* {@code Integer.MAX_VALUE}.
*
* @return the number of elements in this set (its cardinality)
*/
public int size() {
return this.internalDictionary.size();
}
/**
* Returns {@code true} if this set contains no elements.
*
* @return {@code true} if this set contains no elements
*/
public boolean isEmpty() {
return this.internalDictionary.isEmpty();
}
/**
* Returns {@code true} if this set contains the specified element.
* More formally, returns {@code true} if and only if this set
* contains an element {@code e} such that
* {@code Objects.equals(o, e)}.
*
* @param e element whose presence in this set is to be tested
* @return {@code true} if this set contains the specified element
*/
public boolean contains(E e) {
return this.internalDictionary.containsKey(e);
}
/**
* Returns an iterator over the elements in this set. The elements are
* returned in no particular order (unless this set is an instance of some
* class that provides a guarantee).
*
* @return an iterator over the elements in this set
*/
@Override
public Iterator<E> iterator() {
return this.internalDictionary.iterator();
}
// Modification Operations
/**
* Adds the specified element to this set if it is not already present
* (optional operation). More formally, adds the specified element
* {@code e} to this set if the set contains no element {@code e2}
* such that
* {@code Objects.equals(e, e2)}.
* If this set already contains the element, the call leaves the set
* unchanged and returns {@code false}. In combination with the
* restriction on constructors, this ensures that sets never contain
* duplicate elements.
*
* @param e element to be added to this set
* @return {@code true} if this set did not already contain the specified
* element
*/
public boolean add(E e) {
return this.internalDictionary.put(e, new Object()) == null;
}
/**
* Removes the specified element from this set if it is present
* (optional operation). More formally, removes an element {@code e}
* such that
* {@code Objects.equals(o, e)}, if
* this set contains such an element. Returns {@code true} if this set
* contained the element (or equivalently, if this set changed as a
* result of the call). (This set will not contain the element once the
* call returns.)
*
* @param e object to be removed from this set, if present
* @return {@code true} if this set contained the specified element
*/
public boolean remove(E e) {
return this.internalDictionary.remove(e) != null;
}
@Override
public String toString() {
StringBuilder b = new StringBuilder();
for (E e : this) {
b.append(e + ", ");
}
if (b.length() > 0) {
b.delete(b.length() - 2, b.length());
}
return "[" + b.toString() + "]";
}
}
package edu.caltech.cs2.project08.bots;
import edu.caltech.cs2.datastructures.ArrayDeque;
import edu.caltech.cs2.interfaces.IDeque;
import edu.caltech.cs2.project08.game.Board;
import edu.caltech.cs2.project08.game.Evaluator;
import edu.caltech.cs2.project08.game.Move;
......@@ -12,6 +14,21 @@ public class AlphaBetaSearcher<B extends Board> extends AbstractSearcher<B> {
}
private static <B extends Board> BestMove alphaBeta(Evaluator<B> evaluator, B board, int depth) {
return null;
ArrayDeque<Move> nextBoards = (ArrayDeque<Move>) board.getMoves();
BestMove bestMove = null;
if (depth == 0 || nextBoards.isEmpty()) {
int score = evaluator.eval(board);
bestMove = new BestMove(score);
} else {
for (Move nextBoard : nextBoards) {
BestMove move = alphaBeta(evaluator, board, depth - 1);
move.negate();
if (bestMove == null || move.score > bestMove.score) {
bestMove = new BestMove(nextBoard, move.score);
}
}
}
return bestMove;
}
}
\ No newline at end of file
package edu.caltech.cs2.project08.bots;
import edu.caltech.cs2.datastructures.ArrayDeque;
import edu.caltech.cs2.project08.board.ArrayBoard;
import edu.caltech.cs2.project08.bots.AbstractSearcher;
import edu.caltech.cs2.project08.bots.BestMove;
import edu.caltech.cs2.project08.game.Board;
import edu.caltech.cs2.project08.game.Evaluator;
import edu.caltech.cs2.project08.game.Move;
......@@ -12,6 +16,24 @@ public class MinimaxSearcher<B extends Board> extends AbstractSearcher<B> {
}
private static <B extends Board> BestMove minimax(Evaluator<B> evaluator, B board, int depth) {
return null;
if (depth == 0 || board.isGameOver()) {
return new BestMove(null, evaluator.eval(board));
}
ArrayDeque<Move> legalMoves = (ArrayDeque<Move>) board.getMoves();
if (legalMoves.isEmpty()) {
return new BestMove(null, evaluator.eval(board));
}
BestMove bestMove = null;
for (Move move : legalMoves) {
board.makeMove(move);
BestMove response = minimax(evaluator, board, depth - 1);
response.negate();
int value = response.score;
if (bestMove == null || value > bestMove.score) {
bestMove = new BestMove(move, value);
}
}
return bestMove;
}
}
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment