// Kismet
// Copyright (C) 1994, Joseph W. Reiss, All Rights Reserved
// jreiss@magnus.acs.ohio-state.edu
/////////////////////////////////////////////////////////////////////////////
// You are free to modify this code as you wish for your own personal use.
// You may only REDISTRIBUTE the code unaltered, with this copyright notice
// and all documentation intact.
//
// If you make any significant changes to this program, please drop me a
// line and let me know!

#import "DieView.h"

typedef int (*SCOREPROC)();

int scoreAces(id dice[5])
  {
    int		tally=0,i;

    for (i=0; i<5; i++)
	if ([dice[i] value] == 1)  tally++;
    return tally;
  }

int scoreDeuces(id dice[5])
  {
    int		tally=0,i;

    for (i=0; i<5; i++)
	if ([dice[i] value] == 2)  tally+=2;
    return tally;
  }

int scoreTreys(id dice[5])
  {
    int		tally=0,i;

    for (i=0; i<5; i++)
	if ([dice[i] value] == 3)  tally+=3;
    return tally;
  }

int scoreFours(id dice[5])
  {
    int		tally=0,i;

    for (i=0; i<5; i++)
	if ([dice[i] value] == 4)  tally+=4;
    return tally;
  }

int scoreFives(id dice[5])
  {
    int		tally=0,i;

    for (i=0; i<5; i++)
	if ([dice[i] value] == 5)  tally+=5;
    return tally;
  }

int scoreSixes(id dice[5])
  {
    int		tally=0,i;

    for (i=0; i<5; i++)
	if ([dice[i] value] == 6)  tally+=6;
    return tally;
  }

int scoreTwoPairSameColor(id dice[5])
  {
    int		counts[6]={0,0,0,0,0,0},tally=0,match=-1,i;

    for (i=0; i<5; i++)
      {
	if (++counts[[dice[i] value]-1] == 2)
	    match = [dice[i] value]-1;
	tally+=[dice[i] value];
      }
    if (match >= 0 && (counts[match] >= 4 || counts[5-match] >= 2))
	return tally;
    else
	return 0;
  }

int scoreThreeOfAKind(id dice[5])
  {
    int		counts[6]={0,0,0,0,0,0},tally=0,i;

    for (i=0; i<5; i++)
      {
	counts[[dice[i] value]-1]++;
	tally+=[dice[i] value];
      }
    if (counts[0]>=3 || counts[1]>=3 ||
	counts[2]>=3 || counts[3]>=3 ||
	counts[4]>=3 || counts[5]>=3)
	return tally;
    else
	return 0;
  }

int scoreStraight(id dice[5])
  {
    int		counts[6]={0,0,0,0,0,0},i;

    for (i=0; i<5; i++)
	counts[[dice[i] value]-1]++;
    if ((counts[0]==1 || counts[5]==1) &&
	counts[1]==1 && counts[2]==1 &&
	counts[3]==1 && counts[4]==1)
	return 30;
    else
	return 0;
  }

int scoreFlush(id dice[5])
  {
    int		val1,val2,i;

    val1 = [dice[0] value];
    val2 = 7-val1;			// Other value with same color is this
    for (i=1; i<5; i++)
	if ([dice[i] value] != val1 &&
	    [dice[i] value] != val2)
	    return 0;
    return 35;
  }

int scoreFullHouse(id dice[5])
  {
    int		val1,val2,cnt1,cnt2,digit,tally=0,i;

    val1 = [dice[0] value];
    cnt1 = 1;
    val2 = -1;
    cnt2 = 0;
    for (i=1; i<5; i++)
      {
	digit = [dice[i] value];
	if (digit == val1)		// Matches first value
	    cnt1++;
	else if (digit == val2)		// Matches second value
	    cnt2++;
	else if (val2 < 0)		// Don't have second value yet
	  {
	    val2 = digit;
	    cnt2 = 1;
	  }
	else
	    return 0;			// We have three different values!
	tally+=[dice[i] value];
      }
    if (cnt1==5 ||			// All the same id value
	(cnt1==3 && cnt2 == 2) ||
	(cnt1==2 && cnt2 == 3))
	return tally+15;
    else
	return 0;
  }

int scoreFullHouseSameColor(id dice[5])
  {
    int		val1,val2,cnt1,cnt2,digit,tally=0,i;

    val1 = [dice[0] value];
    cnt1 = 1;
    val2 = 7-val1;			// Other value with same color is this
    cnt2 = 0;
    for (i=1; i<5; i++)
      {
	digit = [dice[i] value];
	if (digit == val1)		// Matches first value
	    cnt1++;
	else if (digit == val2)		// Matches second value
	    cnt2++;
	else
	    return 0;			// We have three different values!
	tally+=[dice[i] value];
      }
    if (cnt1==5 ||			// All the same id value
	(cnt1==3 && cnt2 == 2) ||
	(cnt1==2 && cnt2 == 3))
	return tally+20;
    else
	return 0;
  }

int scoreFourOfAKind(id dice[5])
  {
    int		counts[6]={0,0,0,0,0,0},tally=0,i;

    for (i=0; i<5; i++)
      {
	counts[[dice[i] value]-1]++;
	tally+=[dice[i] value];
      }
    if (counts[0]>=4 || counts[1]>=4 ||
	counts[2]>=4 || counts[3]>=4 ||
	counts[4]>=4 || counts[5]>=4)
	return tally+25;
    else
	return 0;
  }

int scoreYarborough(id dice[5])
  {
    int		tally=0,i;

    for (i=0; i<5; i++)
	tally+=[dice[i] value];
    return tally;
  }

int scoreKismet(id dice[5])
  {
    int		digit,i;

    digit = [dice[0] value];
    for (i=1; i<5; i++)
      {
	if ([dice[i] value] != digit)
	    return 0;
      }
    return digit*5+50;
  }

///////////////////////////////////////////////////////////////////////

static SCOREPROC scoring[] = {
    scoreAces,
    scoreDeuces,
    scoreTreys,
    scoreFours,
    scoreFives,
    scoreSixes,

    scoreTwoPairSameColor,
    scoreThreeOfAKind,
    scoreStraight,
    scoreFlush,
    scoreFullHouse,
    scoreFullHouseSameColor,
    scoreFourOfAKind,
    scoreYarborough,
    scoreKismet
};

int scoreThis(id dice[5], int tag)
  {
    return (*scoring[tag])(dice);
  }
