Penguin Pete's Link <--Back to Penguin Pete's Home Page
make_a_word.sh

#!/bin/bash

# The "How many words can you make from the letters of $word?" game
# prints random word from /usr/share/dict/words
# waits for input
# on input:
# checks for "!" if found, exits
# tests enterred word to see if it is in the dictionary
# tests to make sure enterred word can be made from $word
# without using letters twice
# on exit:
# reports score (number of correct words found)
#
# NOTE: "lettertest" is my compiled C program, in an
# accessible directory!
#

check_letters() {
lettertest $getword $answer
if [ "$?" != 0 ]; then
check=0
else
check=1
fi
}

score=0
wordcount=$(wc -w /usr/share/dict/words | awk '{print $1}')
pick=$(($RANDOM % $wordcount))
pick=$(($pick+1))
sedfeed=$pick"p"
getword=$(sed -n "$sedfeed" /usr/share/dict/words)
echo "! to quit. How many words can you make from:"
echo $getword
while [ "$answer" != "!" ]; do
read answer
if [ "$answer" != "!" ]; then
grep "\<$answer\>" /usr/share/dict/words > /dev/null
if [ "$?" != 0 ]; then
echo $answer is not a word, try again!
else
check_letters
if [ "$check" == 0 ]; then
echo $answer is not found in $getword
else
score=$(($score+1))
echo $answer >> /tmp/words
fi
fi
fi
done
echo You scored $score words.

exit 0


getsite.sh

#!/bin/bash

# A trivial little wrapper for wget. Conveniently downloads a site,
# converts the links, and tar&gzips it for easy porting, leaving the
# site folder for you to delete after you check it to make sure it
# got what you wanted. Usefull for downloading a web-published
# "book" (such as a software manual) all in one piece from the
# table-of-contents page.

if [ "$#" != "2" ]; then
echo "Usage: getsite site_URL_index your_folder"
exit 0
fi

wget --mirror -w 2 -p --html-extension --convert-links -P ./$2 $1

tar -cf $2.tar $2
gzip $2.tar

exit 0


term_color.sh

#!/bin/bash

# term_color
# turn ANSI text formatting escape sequences on/off

# WARNING: ANSI escape sequences are notoriously flaky - what works
# fine on one machine will not work on another, depending
# on what kind of support the terminal has! Use with caution,
# testing, and apologies

# this script provides a convenient shorthand for
# calling ANSI escape sequences at the terminal
# can be operated independently or
# called from other scripts/programs

# Usage: "term_color [command]" | "term_color [fg color] [bg color]"
# commands:
# invon/invoff - inverse on/off
# boldon/boldoff - bold on/off
# iton/itoff - italics on/off
# ulon/uloff - underlining on/off
# [0-7] [0-7] - colors
# normal - normal

# color may be specified with one numerical argument only
# for foreground color, or two arguments for foreground/background

comm1=$1
comm2=$2

# inverse color on/off
if [ "$comm1" = "invon" ]; then
echo -e '\E[7m'
fi
if [ "$comm1" = "invoff" ]; then
echo -e '\E[27m'
fi

# bold on/off
if [ "$comm1" = "boldon" ]; then
echo -e '\E[1m'
fi
if [ "$comm1" = "boldoff" ]; then
echo -e '\E[22m'
fi

# italics on/off
if [ "$comm1" = "iton" ]; then
echo -e '\E[3m'
fi
if [ "$comm1" = "itoff" ]; then
echo -e '\E[23m'
fi

# underlining on/off
if [ "$comm1" = "ulon" ]; then
echo -e '\E[4m'
fi
if [ "$comm1" = "uloff" ]; then
echo -e '\E[24m'
fi

# foreground colors on
if [ "$comm1" = "0" ]; then
echo -e '\E[30m'
fi
if [ "$comm1" = "1" ]; then
echo -e '\E[31m'
fi
if [ "$comm1" = "2" ]; then
echo -e '\E[32m'
fi
if [ "$comm1" = "3" ]; then
echo -e '\E[33m'
fi
if [ "$comm1" = "4" ]; then
echo -e '\E[34m'
fi
if [ "$comm1" = "5" ]; then
echo -e '\E[35m'
fi
if [ "$comm1" = "6" ]; then
echo -e '\E[36m'
fi
if [ "$comm1" = "7" ]; then
echo -e '\E[37m'
fi

# background colors on
if [ "$comm2" = "0" ]; then
echo -e '\E[40m'
fi
if [ "$comm2" = "1" ]; then
echo -e '\E[41m'
fi
if [ "$comm2" = "2" ]; then
echo -e '\E[42m'
fi
if [ "$comm2" = "3" ]; then
echo -e '\E[43m'
fi
if [ "$comm2" = "4" ]; then
echo -e '\E[44m'
fi
if [ "$comm2" = "5" ]; then
echo -e '\E[45m'
fi
if [ "$comm2" = "6" ]; then
echo -e '\E[46m'
fi
if [ "$comm2" = "7" ]; then
echo -e '\E[47m'
fi

# everything back to normal
if [ "$comm1" = "normal" ]; then
echo -e '\E[0m'
fi

exit 0


lettertest.c

/*
* lettertest.c
* Usage: "lettertest $string1 $string2"
* returns 0 if all of the letters of string2 may be found in
* string1 without using any letters more than once !
* else it returns 1
* check it's return value with "echo $?"
*
* I wrote this to support my "make_a_word" shell script,
* but it should have broad applications for any
* number of word-game programs.
*
* compile with a simple "gcc -o lettertest lettertest.c"
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

int
main (int argc, char *argv[])
{
if (argc != 3)
{
printf ("feed me two strings, dummy!\n");
exit (2);
}
char getword[strlen (argv[1])];
char guess[strlen (argv[2])];
sprintf (getword, argv[1]);
sprintf (guess, argv[2]);
int l1, l2;
int findtest;
int intest = 0;
for (l1 = 0; l1 < strlen (guess); l1++)
{
findtest = 0;
for (l2 = 0; l2 < strlen (getword); l2++)
{
if (!findtest)
{
if (guess[l1] == getword[l2])
{
findtest = 1;
getword[l2] = '@';
/* to ensure that we use each
letter once and once only! */
}
}
}
if (!findtest)
{
intest = 1;
break;
}
}
/* As explained above, this program is intended only to
support word-game programs, so only the return value
would be used. However, for human-readable direct
output, just uncomment this block! */

/*
if(!intest)
printf("%s is found in %s.\n",argv[2],argv[1]);
else
printf("%s is NOT found in %s.\n",argv[2],argv[1]);
*/

return intest;
}


life_SDL.c

/* Life_SDL.c - by Pete Trbovich, Des Moines, Iowa, 2/20/06
* Conway's Life simulation done with SDL.
*/

#include "SDL.h"
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>

#define WHITE SDL_MapRGB(screen->format,255,255,255)
#define BLACK SDL_MapRGB(screen->format,0,0,0)

/* Wrappers for SDL's raving-mad pixel-drawing routines */
void putpixel (SDL_Surface * surface, int x, int y, Uint32 pixel);
void draw_pix (int x, int y, Uint32 ccc);
/* To use, call draw_pix(320,240,SDL_MapRGB(screen->format,255,255,255));
,for instance */

void draw_cell (int x, int y, int s); /* x-y coords, 's'="status" (alive,dead) */
void check_interrupt (void); /* event polling: 'q' 'esc' (clicking
window X) to quit, 'r' to reset */
SDL_Surface *screen;
SDL_Event event;

/* 640x480 grid, cells are 10x10, hence the grid is 64x48. To change to, say,
800x600, s/64/80/g and s/48/60/g . Why I didn't think of using a #define
here? */
int Grid[64][48]; /* the action! */
int Alive[64][48]; /* poll the last generation... */
int loop1, loop2;
int quitflag = 0;
int lifecheck;
int resetflag = 1; /* to start a new "universe" */

int
main ()
{
srand (time (NULL));
SDL_Init (SDL_INIT_VIDEO);
atexit (SDL_Quit);
screen = SDL_SetVideoMode (640, 480, 16, SDL_SWSURFACE);
SDL_WM_SetCaption ("Life_SDL", NULL);

while (quitflag == 0)
{
if (resetflag)
{
/* randomly initialize the grid */
for (loop1 = 0; loop1 < 64; loop1++)
for (loop2 = 0; loop2 < 48; loop2++)
{
Alive[loop1][loop2] = rand () % 2;
/* necessary for when user resets */
Grid[loop1][loop2] = 0;
}
resetflag = 0;
}
for (loop1 = 0; loop1 < 64; loop1++)
for (loop2 = 0; loop2 < 48; loop2++)
{
Grid[loop1][loop2] = Alive[loop1][loop2];
draw_cell (loop1, loop2, Grid[loop1][loop2]);
check_interrupt ();
}
for (loop1 = 0; loop1 < 64; loop1++)
for (loop2 = 0; loop2 < 48; loop2++)
{
/* The Formula! */
lifecheck = 0;
lifecheck =
Grid[((loop1 - 1) + 64) % 64][((loop2 - 1) + 48) % 48] +
Grid[((loop1 - 1) + 64) % 64][loop2] +
Grid[((loop1 - 1) + 64) % 64][((loop2 + 1) + 48) % 48] +
Grid[loop1][((loop2 - 1) + 48) % 48] +
Grid[loop1][((loop2 + 1) + 48) % 48] +
Grid[((loop1 + 1) + 64) % 64][((loop2 - 1) + 48) % 48] +
Grid[((loop1 + 1) + 64) % 64][loop2] +
Grid[((loop1 + 1) + 64) % 64][((loop2 + 1) + 48) % 48];

switch (lifecheck)
{
case 2:
if (Grid[loop1][loop2] == 1)
Alive[loop1][loop2] = 1;
break;
case 3:
Alive[loop1][loop2] = 1;
break;
default:
Alive[loop1][loop2] = 0;
break;
}
check_interrupt ();
}
SDL_UpdateRect (screen, 0, 0, 0, 0);
}
/* we don't return 42 here because the value of
the universe and everything is 21 each. */
return 0;
}

void
check_interrupt (void)
{
SDL_PollEvent (&event);
if (event.type == SDL_KEYDOWN)
{
/* Either 'q' or 'esc' exits */
switch (event.key.keysym.sym)
{
case SDLK_ESCAPE:
quitflag = 1;
break;
case SDLK_q:
quitflag = 1;
break;
case SDLK_r:
resetflag = 1;
break;
default:
break;
}
}
else
{
/* click 'X' on windowbar exits, too */
if (event.type == SDL_QUIT)
quitflag = 1;
}
}

void
draw_cell (int x, int y, int s)
{
int l1, l2;
for (l1 = 0; l1 < 10; l1++)
for (l2 = 0; l2 < 10; l2++)
draw_pix (x * 10 + l1, y * 10 + l2, (s == 0) ? BLACK : WHITE);
}

void
draw_pix (int x, int y, Uint32 ccc)
{
SDL_LockSurface (screen);
putpixel (screen, x, y, ccc);
SDL_UnlockSurface (screen);
}

void
putpixel (SDL_Surface * surface, int x, int y, Uint32 pixel)
{
int bpp = surface->format->BytesPerPixel;
Uint8 *p = (Uint8 *) surface->pixels + y * surface->pitch + x * bpp;
switch (bpp)
{
case 1:
*p = pixel;
break;
case 2:
*(Uint16 *) p = pixel;
break;
case 3:
if (SDL_BYTEORDER == SDL_BIG_ENDIAN)
{
p[0] = (pixel >> 16) & 0xff;
p[1] = (pixel >> 8) & 0xff;
p[2] = pixel & 0xff;
}
else
{
p[0] = pixel & 0xff;
p[1] = (pixel >> 8) & 0xff;
p[2] = (pixel >> 16) & 0xff;
}
break;
case 4:
*(Uint32 *) p = pixel;
break;
}
}


poker_eval.c

/*
* poker_eval.c by Pete Trbovich, Des Moines, Iowa, 4/30/05
*
* pass it a five-arguement poker hand, it'll print out an
* evaluation. Designed to be suitable to co-operate with any
* program in any language, but in order to work, it has to
* be unusually picky about it's data! Just do a system call
* to this program and catch the output in your customary manner!
*
* FORMAT:
* The ranks MUST be:
* A 2 3 4 5 6 7 8 9 T J Q K
* for Ace, duece, tray, 4, 5, 6, 7, 8, 9, Ten, Jack, Queen, King
*
* The suits MUST be:
* h s c d
* for hearts, spades, clubs, diamonds
*
* And they have to be presented:
* Rank first, then suit, then a single space to seperate the next card.
*
* Examples:
* Ah Kd 4d 4s 4c
* returns ==> "three of a kind"
*
* Jc Qc Ac Kc Tc
* returns ==> "royal flush"
*
* The card tokens do not have to be sorted in any particular order.
* Note that this routine does not handle wild cards. My suggestion,
* support wild cards in your own code, perhaps by iterating through
* each possible card value for each wild card while calling this
* program, saving the highest possible value. Later, I may rewrite
* this for wild-card support...I'm tempted to suggest wild cards
* be tokenized as double asterisks :-) but that might cause trouble
* on the command line...
*
* Compile it the regular ordinary vanilla way:
* "gcc -o poker_eval poker_eval.c"
*
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main(int argc,char *argv[])
{
struct card_hand
{
char card[3];
}H[5];
/* for looping: */
int lll;

char rank[5];
char suit[5];

/* for rank polling, 0=A, 12=K */
int rank_count[13]={0,0,0,0,0,0,0,0,0,0,0,0,0};
/* for suit polling, 0=hearts, 1=spades, 2=clubs, 3=diamonds */
int suit_count[4]={0,0,0,0};

char result[32];

sprintf(result,"nothing");

if(argc!=6)
{
printf("Usage: pass a poker hand in, get an evaluation out\n");
printf("Takes EXACTLY five args.\n");
printf("View source file for instructions as to formatting\n");
exit(0);
}
for(lll=0;lll<5;lll++)
{
if(strlen(argv[lll+1])!=2)
{
printf("Hand string incorrectly formatted.\n");
printf("View source file for instructions as to formatting\n");
exit(1);
}
else
{
strcpy(H[lll].card,argv[lll+1]);
}
}

for(lll=0;lll<5;lll++)
{
switch(H[lll].card[0])
{
case 'A':
rank[lll]=H[lll].card[0];
rank_count[0]++;
break;
case '2':
rank[lll]=H[lll].card[0];
rank_count[1]++;
break;
case '3':
rank[lll]=H[lll].card[0];
rank_count[2]++;
break;
case '4':
rank[lll]=H[lll].card[0];
rank_count[3]++;
break;
case '5':
rank[lll]=H[lll].card[0];
rank_count[4]++;
break;
case '6':
rank[lll]=H[lll].card[0];
rank_count[5]++;
break;
case '7':
rank[lll]=H[lll].card[0];
rank_count[6]++;
break;
case '8':
rank[lll]=H[lll].card[0];
rank_count[7]++;
break;
case '9':
rank[lll]=H[lll].card[0];
rank_count[8]++;
break;
case 'T':
rank[lll]=H[lll].card[0];
rank_count[9]++;
break;
case 'J':
rank[lll]=H[lll].card[0];
rank_count[10]++;
break;
case 'Q':
rank[lll]=H[lll].card[0];
rank_count[11]++;
break;
case 'K':
rank[lll]=H[lll].card[0];
rank_count[12]++;
break;
default:
printf("Hand string incorrectly formatted.\n");
printf("View source file for instructions as to formatting\n");
exit(1);
break;
}
switch(H[lll].card[1])
{
case 'h':
suit[lll]=H[lll].card[1];
suit_count[0]++;
break;
case 's':
suit[lll]=H[lll].card[1];
suit_count[1]++;
break;
case 'c':
suit[lll]=H[lll].card[1];
suit_count[2]++;
break;
case 'd':
suit[lll]=H[lll].card[1];
suit_count[3]++;
break;
default:
printf("Hand string incorrectly formatted.\n");
printf("View source file for instructions as to formatting\n");
exit(1);
break;
}
}

/* pre-check for straight */
int straight=0;
if((rank_count[0]==1)&&(rank_count[1]==1)&&(rank_count[2]==1)&&
(rank_count[3]==1)&&(rank_count[4]==1))
straight=1;
if((rank_count[1]==1)&&(rank_count[2]==1)&&(rank_count[3]==1)&&
(rank_count[4]==1)&&(rank_count[5]==1))
straight=1;
if((rank_count[2]==1)&&(rank_count[3]==1)&&(rank_count[4]==1)&&
(rank_count[5]==1)&&(rank_count[6]==1))
straight=1;
if((rank_count[3]==1)&&(rank_count[4]==1)&&(rank_count[5]==1)&&
(rank_count[6]==1)&&(rank_count[7]==1))
straight=1;
if((rank_count[4]==1)&&(rank_count[5]==1)&&(rank_count[6]==1)&&
(rank_count[7]==1)&&(rank_count[8]==1))
straight=1;
if((rank_count[5]==1)&&(rank_count[6]==1)&&(rank_count[7]==1)&&
(rank_count[8]==1)&&(rank_count[9]==1))
straight=1;
if((rank_count[6]==1)&&(rank_count[7]==1)&&(rank_count[8]==1)&&
(rank_count[9]==1)&&(rank_count[10]==1))
straight=1;
if((rank_count[7]==1)&&(rank_count[8]==1)&&(rank_count[9]==1)&&
(rank_count[10]==1)&&(rank_count[11]==1))
straight=1;
if((rank_count[8]==1)&&(rank_count[9]==1)&&(rank_count[10]==1)&&
(rank_count[11]==1)&&(rank_count[12]==1))
straight=1;
if((rank_count[9]==1)&&(rank_count[10]==1)&&(rank_count[11]==1)&&
(rank_count[12]==1)&&(rank_count[0]==1))
straight=1;

/* pre-check for flushes */
int suit_same=0;
if((suit[0]==suit[1])&&(suit[1]==suit[2])&&
(suit[2]==suit[3])&&(suit[3]==suit[4]))
suit_same=1;

/* pre-check for multiples of two, three, four*/
int pair_rank=0;
int two_kind=0;
int three_kind=0;
int four_kind=0;
for(lll=0;lll<13;lll++)
{
if(rank_count[lll]==4)
four_kind=1;
if(rank_count[lll]==3)
three_kind=1;
if(rank_count[lll]==2)
{
two_kind=1;
pair_rank=lll;
}
}

/* check for royal */
if((rank_count[12]==1)&&(rank_count[11]==1)&&(rank_count[10]==1)&&
(rank_count[9]==1)&&(rank_count[0]==1)&&(suit_same))
sprintf(result,"royal flush");

/* check for straight flush */
if(!strcmp(result,"nothing"))
{
if((straight)&&(suit_same))
sprintf(result,"straight flush");
}

/* check for four of a kind */
if(!strcmp(result,"nothing"))
{
if(four_kind)
sprintf(result,"four of a kind");
}

/* check for full house */
if(!strcmp(result,"nothing"))
{
if((three_kind)&&(two_kind))
sprintf(result,"full house");
}

/* check for flush */
if(!strcmp(result,"nothing"))
{
if(suit_same)
sprintf(result,"flush");
}

/* check for straight */
if(!strcmp(result,"nothing"))
{
if(straight)
sprintf(result,"straight");
}

/* check for three of a kind */
if(!strcmp(result,"nothing"))
{
if(three_kind)
sprintf(result,"three of a kind");
}

/* check for two pairs */
int pair_count=0;
if(!strcmp(result,"nothing"))
{
for(lll=0;lll<13;lll++)
{
if(rank_count[lll]==2)
pair_count++;
}
if(pair_count==2)
sprintf(result,"two pair");
}

/* check for jacks or better */
if(!strcmp(result,"nothing"))
{
if((two_kind)&&((pair_rank>9)||(pair_rank==0)))
sprintf(result,"jacks or better");
}

printf("%s\n",result);
exit(0);
}


markov.py

#! /usr/bin/env python

# markov.py
# by Pete Trbovich, Des Moines, Iowa, 12/31/05

# A simple markov chain generator - reads in files and composes
# a dictionary, then generates random sentences!
# Great fun at parties!

# Usage: In this amatuer and clunky version, the program
# looks for all readable text files in your immediate
# directory and loads each one. If it already has
# a word, it will add the following words it finds
# to the entry for that word. Else, it creates a new
# entry. When it's done scarfing files, you will get
# a prompt, prompting you with "more?". At this
# prompt, type a word. It will use that word as the
# first word of ten newly generated sentences. Type a
# blank line again to quit - if you can force yourself!

# This is my second version, much better implementations lie in
# the future. In the meantime, I suggest feeding it lots and
# lots of files. Like:
#
# Turn it loose on your fortune cookie folder!
# Download the Jargon file as text and feed it in!
# Run source files from different programming languages through it and see
# it invent a new language before your eyes!
# Use it to mock your least favorite Slashdot flamer!
# Feed it your business emails and see how long it takes to do a perfect
# imitation of your boss!
# Feed it poems and publish the results - it can't be worse than
# what you see getting published all the time!
# You can even copy the posts from my "Penguin Pete's" blog and use this to
# produce an *even* *more* deranged version of me!

import os
import sys
import string
import random
import commands

end_words=[]
punct="!.?"
alph="abcdefghijklmnopqrstuvwxyz-\'"
dict={}

def talk(response):
print string.capitalize(response),
word=response
sentence_length=random.randint(5,15)
while sentence_length > 0 and dict.has_key(word):
new_word=dict[word][random.randint(0,len(dict[word])-1)]
print new_word,
word=new_word
sentence_length=sentence_length-1
if sentence_length == 0 and word not in end_words:
sentence_length=1
print punct[random.randint(0,2)]

def isalpha(c):
test=0
if alph.find(c) != -1:
test=1
return test

def ispunct(c):
test=0
if punct.find(c) != -1:
test=1
return test

def readword(current_file):
c=string.lower(current_file.read(1))
word=""
while c != " " and isalpha(c) == 1 and len(c) > 0:
if c != " " and isalpha(c) == 1 and len(c) > 0:
word=word+c
c=string.lower(current_file.read(1))
if ispunct(c) and len(c) > 0:
word=word+'!'
if not len(c) > 0:
word="EOF"
return word

def load_dict(current_file):
Word=" "
LastWord=""
end_sentence_flag=0
while Word != "EOF":
Word=readword(current_file)
if Word != "EOF" and len(Word) > 0:
if ispunct(Word[len(Word)-1:]):
Word=Word[0:len(Word)-1]
end_sentence_flag=1
if not LastWord:
LastWord=Word
else:
if not dict.has_key(LastWord):
dict[LastWord]=[Word]
else:
dict[LastWord]=dict[LastWord]+[Word]
if end_sentence_flag:
LastWord=""
end_words.append(Word)
end_sentence_flag=0
else:
LastWord=Word

def find_text_files():
filelist=os.listdir("./")
for l in filelist:
filename=""
comm="file "+l+" | grep 'text' | grep -v 'markov' | sed 's/:.*$//'"
filename=commands.getoutput(comm)
if filename:
print "Loading..."+filename
current_file=open(filename,"r")
load_dict(current_file)
current_file.close()

find_text_files()
response=" "
while response:
response=raw_input("more? ")
if response:
for i in range(1,10):
talk(response)


runegen.py

#! /usr/bin/env python

# runegen.py - by Pete Trbovich, Des Moines, Iowa, 1/16/06

"""Frivolous rune-name generator.

Usage: Give it a string, it returns a combination
of runes derived from that string. You can
give it your name and have a two-rune title
to use for an internet handle, for
instance. Uses the Elder Futhark.
"""

import sys

rune_list=('Fehu', 'Uruz', 'Thurisaz', 'Ansuz',
'Raidho', 'Kenaz', 'Gebo', 'Wunjo',
'Hagalaz', 'Nauthiz', 'Isa', 'Jera',
'Eihwaz', 'Perthro', 'Algiz', 'Sowilo'
'Tiwaz', 'Berkano', 'Ehwaz', 'Mannaz',
'Laguz', 'Ingwaz', 'Dagaz', 'Othala')

Str=sys.argv
String_base=[]
for i in range(1,len(Str[1:])+1):
String_base.extend(list(Str[i]))
num=0
for i in range(0,len(String_base)):
num+=ord(String_base[i])
number=divmod(num,24)
print rune_list[number[0] % 24], rune_list[number[1]]

# Standard disclaimer: for amusement purposes only.
# So of course, guaranteed to be as accurate as
# astrology, numerology, biorythms, Tarot cards,
# tea-leaf reading, etc. That being said, my name
# works out to "Ansuz(A revealing message or insight,
# communication.) Wunjo(Joy, comfort, pleasure.)"
# So, I take pleasure in communicating. No
# wonder I have a blog!


poker.py

#! /usr/bin/env python

# An updated command-line card game.
# Deals five random cards and gives you
# the chance to save them, then redeals
# the ones you don't save. Finally, it
# calls my poker_eval.c program to
# evaluate the hand.

import commands
import random
deck_code=['Ad ','Kd ','Qd ','Jd ','Td ','9d ','8d ','7d ','6d ',\
'5d ','4d ','3d ','2d ',\
'As ','Ks ','Qs ','Js ','Ts ','9s ','8s ','7s ','6s ',\
'5s ','4s ','3s ','2s ',\
'Ah ','Kh ','Qh ','Jh ','Th ','9h ','8h ','7h ','6h ',\
'5h ','4h ','3h ','2h ',\
'Ac ','Kc ','Qc ','Jc ','Tc ','9c ','8c ','7c ','6c ',\
'5c ','4c ','3c ','2c ']

new_deck=['A diamonds ','K diamonds ','Q diamonds ','J diamonds ',\
'10 diamonds ','9 diamonds ','8 diamonds ','7 diamonds ',\
'6 diamonds ','5 diamonds ','4 diamonds ','3 diamonds ',\
'2 diamonds ',\
'A spades ','K spades ','Q spades ','J spades ',\
'10 spades ','9 spades ','8 spades ','7 spades ',\
'6 spades ','5 spades ','4 spades ','3 spades ',\
'2 spades ',\
'A hearts ','K hearts ','Q hearts ','J hearts ',\
'10 hearts ','9 hearts ','8 hearts ','7 hearts ',\
'6 hearts ','5 hearts ','4 hearts ','3 hearts ',\
'2 hearts ',\
'A clubs ','K clubs ','Q clubs ','J clubs ',\
'10 clubs ','9 clubs ','8 clubs ','7 clubs ',\
'6 clubs ','5 clubs ','4 clubs ','3 clubs ',\
'2 clubs ']

deck=[' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',\
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',\
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',\
' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ']
hand=[' ',' ',' ',' ',' ']
hand_code=[' ',' ',' ',' ',' ']

# OK, the above string array initialization is retarded.
# This is what happens when you break between 3 days of writing PHP
# and two days of writing a gallery generator in Bash, sed, and awk
# which may *never* get finished!:
# you write a toy in Python and go completely insane.
# I'll post the correct solution here as soon as I remember it.

def shuffle():
for i in range(len(new_deck)):
deck[i]=new_deck[i]
count=0
while count < 300:
count=count+1
pick1=random.randint(0,51)
pick2=random.randint(0,51)
first_card=deck[pick1]
second_card=deck[pick2]
deck[pick1]=second_card
deck[pick2]=first_card
first_card=deck_code[pick1]
second_card=deck_code[pick2]
deck_code[pick1]=second_card
deck_code[pick2]=first_card

def deal():
count=0
while count < 5:
hand[count]=deck[count]
hand_code[count]=deck_code[count]
print hand[count],
count=count+1

def hand_status():
count=0
while count < 5:
print hand[count],
count=count+1
print
count=0
while count < 5:
if saved[count]==1:
print 'saved ',
else:
print ' ',
count=count+1

def redeal():
count=0
while count < 5:
if saved[count]==0:
hand[count]=deck[count+5]
hand_code[count]=deck_code[count+5]
print hand[count],
count=count+1

shuffle()
deal()
print
saved=[0,0,0,0,0]
select=1
while not select==0:
select=int(input("type 1 to 5 +Enter to save a card, 0 to redeal "))
print
if not select==0:
save_it=select-1
saved[save_it]=1
hand_status()
print
redeal()
print
eval_command='poker_eval '+hand_code[0]+hand_code[1]\
+hand_code[2]+hand_code[3]+hand_code[4]
print commands.getoutput(eval_command)

fortuneteller.tcl

#!/usr/bin/wish

# Tcl/Tk/wish dialog, prints fortunes.

proc get_fortune {} {
.txt insert 1.0 ""
set quote [exec fortune]
.txt insert end "$quote \n\n\n"
}

button .again -text "another" -command "get_fortune"
button .stop -text "quit" -command "exit"
frame .textarea
text .txt -width 80 -height 20 -yscrollcommand ".srl_y set"
scrollbar .srl_y -command ".txt yview" -orient v
grid .txt -in .textarea -row 1 -column 1
grid .srl_y -in .textarea -row 1 -column 2 -sticky ns
pack .again
pack .stop
pack .textarea
get_fortune


setBG.tcl

#!/usr/bin/wish

# Tcl/Tk/wish dialog, front-end for the Fluxbox window
# manager's fbsetbg utility. Pick the wallpaper from
# the file dialog; it does the rest. It also saves the
# full-path filename in a file called ".myBG" in your
# home directory, which you can use from your Fluxbox
# init file to call with RootCommand when you restart
# Fluxbox and want it to remember your last wallpaper.

# But none of this works unless you replace
# "/home/*you/wallpapers" with your own image
# directory! So be sure to do that before using.

proc set_BG {} {
set BG [tk_getOpenFile -initialdir /home/*you/wallpapers]
if {$BG != ""} {
exec fbsetbg -f $BG
set outfile [open "/home/*you/.myBG" w]
puts $outfile $BG
close $outfile
}
}

label .instr -text "pick a background from the menu:"
pack .instr
button .get -text "pickBG" -command "set_BG"
pack .get


Captcha.sh

#!/bin/bash

# This is one of three parts of my script to produce images of slightly-distorted
# text known as "captchas", those things you have to type in the letters and
# numbers shown in order to prove you're not a bot/script when you post to or
# join a site.
# The other two pieces are "post_captcha.sh" and "captcha_include".

# You will need: POVray 3D ray-tracing program, BASH, and Image Magick
# (I.M. for converting the image files to .jpg's.)
#
# How it works:
# (1) Replace "/path/to/your/fonts/" with the directory where
# fonts live on your system.
# (2) Replace "yourfont1.ttf, yourfont2.ttf, etc" with the names of the fonts
# you want to generate images with. POVray uses True-Type fonts without
# incident - others may be used, but you'd also have to edit another part.
# This script is set up to use true type fonts and they work. I don't have it
# scrape your fonts directory and load them all, because you should pick and
# choose which fonts to use - not every pretty font works well with this system.
# (3) Either create a directory underneath the location of these scripts called
# "captcha_images" or edit the line at the bottom of this script calling that
# directory - it's just an idea.
# (4) Make sure the other two scripts are in the same directory as wherever you
# put this script. "chmod +x" (make executable) this script and
# "post_captcha.sh" but you don't have to do anything to "captcha_include"
# - this script will digest it.

# How to use: Call it from the command line. Without arguments, it will generate just one.
# With a numerical argument, it will produce that many unique images.
# Example: "Captcha.sh 500" will make 500 captchas.

# What it does: It will pick randomly from your list of fonts, assemble a random
# 6-character string, pick a random number seed, and put all of these
# plus the "captcha_include" together into a new script called "captcha.pov".
# Then it calls POVray to execute the generated file. POVray by default will
# save this image as "captcha.png". This script will then convert it to .jpg
# and name it for it's own random-string. Example: A captcha showing "ADF6G7"
# will be saved as "ADF6G7.jpg".

# The "post_captcha.sh" script is to be run both optionally and seperately. This will
# give you a chance to quality-check the images and weed out any that turned out illegible
# (I had about an 8% junk rate - so 92% of the images produced should be easily read by
# the average online user. And that's with using mostly conservative fonts!)

fontdir="/path/to/your/fonts/"

font=( yourfont1.ttf, yourfont2.ttf, etc )

chars=( A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 2 3 4 6 7 8 9 )

if [ $# = 0 ]; then
loop_number=1
else
loop_number=$1
fi
count=0

while [ $count -lt $loop_number ]; do

randstring=${chars[$RANDOM % 33]}${chars[$RANDOM % 33]}${chars[$RANDOM % 33]}\
${chars[$RANDOM % 33]}${chars[$RANDOM % 33]}${chars[$RANDOM % 33]}
randfont=$fontdir${font[$RANDOM % 34]}
randseed=$(($(($RANDOM % 999999999))*$(($RANDOM % 999999999))))

echo "#declare randfont=\""$randfont"\";" > ./captcha.pov
echo "#declare randstring=\""$randstring"\";" >> ./captcha.pov
echo "#declare R=seed("$randseed");" >> ./captcha.pov

cat ./captcha_include >> ./captcha.pov

povray captcha.pov

convert ./captcha.png ./captcha.jpg
rm ./captcha.png
mv ./captcha.jpg ./captcha_images/$randstring.jpg

count=$(($count+1))

done

exit 0

captcha_include

// captcha_include - NOT meant to be run by itself! This is just one of
// three file for my scripted captcha-generation system - the other two
// are the BASH scripts "Captcha.sh" and "post_captcha.sh" - see
// the comments of "Captcha.sh" for instructions. This is POVray code.


text {
ttf randfont randstring
rand(R), <0, 0>
texture{pigment{color rgb <rand(R),rand(R),rand(R)>}
finish {
diffuse rand(R) brilliance rand(R)*3
phong rand(R) phong_size rand(R)*40
specular rand(R) roughness rand(R)/10
irid { rand(R)
thickness rand(R)
turbulence rand(R) }
}}
scale 1
rotate <0,(rand(R)*30)-15, (rand(R)*30)-15>
translate x*(-2.5)
}

light_source {<(rand(R)*6)-3,(rand(R)*6)-3,-5>,
rgb<rand(R),rand(R),rand(R)>}

sky_sphere{pigment{bozo
turbulence <rand(R),rand(R),rand(R)>
scale rand(R)/2
color_map {
[ 0.1 color rgb <rand(R),rand(R),rand(R)>]
[ 0.9 color rgb <rand(R),rand(R),rand(R)>]
}
}
}

camera {
perspective
location <0, 0, -5>
sky <0, 1, 0>
direction <0, 0, 1>
right <1.3333, 0, 0>
up <0, 1, 0>
look_at <0, 0, 0>
}

global_settings {
adc_bailout 0.00392157
assumed_gamma 1.5
noise_generator 2
}


post_captcha.sh

#!/bin/bash

# One of three files in my scripted captcha-generating system - the
# other two are "Captcha.sh" and "captcha_include". See the comments
# in "Captcha.sh" for instructions, then come here.

# Usage: Given that you have already generated the captcha images in
# a subfolder called "captcha_images" and you have quality-checked them
# in an image viewer such as gthumb or GQView and deleted those of
# unacceptible quality: running this script will rename each captcha file
# "1.jpg", "2.jpg", "3.jpg", etc. It will also generate a text file in the
# same directory which lists the original captcha code strings in the same
# order - do NOT re-arrange the list or rename the image files after this
# or you'll have mis-matched images and codes!

# You are now ready to load the folder with the captcha images and the
# codelist to your server. Your webpage can then display the image and
# allow the user to type in the code, which is then verified from the text
# file. Remember that the code-list's lines will start indexing at 0, but
# your first image file will be named "1.jpg"!

# Yes, it's a kludge and I don't recommend this system at all, but if you're
# stuck with a server incapable of generating it's own captchas, or bots get
# smart enough to read the simple images generated "on the fly" by today's
# methods, this is a possible solution.

ls ./captcha_images/ | sed 's/\.jpg//g' > ./codelist
filecount=$(ls ./captcha_images/ | wc -l)
count=1

while [ $count -le $filecount ]; do
sedfeed=$count"p"
filename=$(sed -n $sedfeed codelist)".jpg"
newfilename=$count".jpg"
mv ./captcha_images/$filename ./captcha_images/$newfilename
count=$(($count+1))
done

mv ./codelist ./captcha_images/codelist

exit