Famous last words celebrities said before death
Many celebrities have passed away, but they are not forgotten to date because of their famous last words that remain to inspire different generations. Even in their weakest conditions at the point of death, they had the bravery to say a final word. The departing words from various celebrities are rich in teaching about life and love, and some are exceptionally funny.
Death has robbed us of several superstars who were icons in different sectors such as musicians, actors, authors, presidents and many more. However, all is not lost because some of the celebrities had the chance to say amazing final words. The words have remained an essential source of inspiration. If you are wondering what some of the celebrities had to say before breathing their last, you have it all here.
Best last words by top celebrities
- "Of course, I know who you are. You're my girl. I love you." - John Wayne
Nigeria’s former first lady Victoria Aguiyi-Ironsi looks full of life as she clocks 90 (video)
The actor died of stomach cancer, and he said these words to his wife.
- "Let's cool it, brothers..." - Malcolm X
Those were the final words of the human right activist before his assassination.
- "I have lived with the prospect of an early death for the last 49 years. I'm not afraid of death, but I'm in no hurry to die. I have so much I want to do first. I regard the brain as a computer which will stop working when its components fail. There is no heaven or afterlife for broken down computers; that is a fairy story for people afraid of the dark." - Stephen Hawking
He said these touching words in an interview before his death at 76 years.
- "I am just going. Have me decently buried, and do not let my body be put into the vault in less than two days after I am dead." - George Washington
- "Money can't buy life." - Bob Marley
Top Shakespeare quotes you need to know
The reggae icon was addressing his son Ziggy after ailing from cancer for a long time.
- "I'm gonna go see Jesus, want to see Jesus." - Whitney Houston
These were the diva’s last words after her stunning performance in Hollywood, California
- "It's better to burn out than to fade away." - Kurt Cobain
These writings were on a note the rock star left.
- "We will be back in five minutes." - Paul Walker
The actor said these words to an engineer at a charity event for typhoon victims. He left the venue in his car which later crashed and burst into flames.
- "I have offended God and mankind because my work did not reach the quality it should have." - Leonardo da Vinci
Shocking final words of celebrities
These are some of the shocking final words uttered by celebrities before their death, and they leave many people astonished and wondering what went through their minds.
Comedian FunnyBone shares mum's photo as he mourns her loss
- "More milk." - Michael Jackson
The pop star did not want real milk, but he referred to propofol which is a powerful hospital anaesthetic.
- "I'm dying." - Steve Irwin
The famed actor said the word to his film crew after being stabbed on the chest by a stingray.
- "Katie, Katie, look...it'll be fine, you know, I just need to get some sleep." - Heath Ledger
The famous actor was talking to his sister during a phone call, and he insisted on taking sleep pills despite her sister’s caution.
- “F**k you.” - Tupac Shakur
The first police officer reported that these were the last words quoted by the legendary rapper before succumbing to gunshot wounds.
- "Mother, I'm going to get my things and get out of this house. Father hates me, and I'm never coming back." - Marvin Gaye
Actress Dakore Egbuson-Akande thanks God as she celebrates 41st birthday (photos)
He was shot at close range by his father as his mother watched. This was after an argument with his father.
- "I'm going away tonight." - James Brown
After arriving for his dental checkup, the dentist observed that the singer was ill and weak and recommended that he sees a doctor
- “I should have never switched from Scotch to Martinis.” - Humphrey Bogart
- “Tomorrow, I shall no longer be here.” - Nostradamus
Funny famous quotes
Some of the last words of famous people are not sorrowful because celebrities use the moment to make funny quotes, which is ironical. If you thought that death is all about pain and sorrow, then you could be wrong because some celebrities made hilarious quotes as their last words before death. Here are some of them;
- "I'm going to the bathroom to read." - Elvis Presley
The musician told his fiancée as he entered the bathroom. His fiancée went to check the bathroom after realizing that he did not return and found him dead.
The life and decease of Sushma Swaraj, the people's favourite leader
- "Stopping for a beer, be there when I can." - Ryan Dunn
These were the actor’s departing words to his fellow actor Bam Margera in a text. He was later involved in a fatal crash leading to his death.
- “Die, my dear? Why that's the last thing, I'll do!” - Groucho Marx
- “I should never have switched from Scotch to Martinis.” - Humphrey Bogart
- “My wallpaper and I are fighting a duel to the death. One of us has got to go.” Oscar Wilde
- “Ah, that tastes nice. Thank you.” - Johannes Brahms
- “I've just had eighteen straight whiskies. I think that's the record.” - Dylan Thomas
- “They couldn't hit an elephant at this dist...” - John Sedgwick
- “I think you're right, Wyatt. I can't see a God dam* thing.”   - Che Guevara
- “I am not the least afraid to die.” - Charles Darwin
- “Don't let it end like this. Tell them I said something.” - Pancho Villa
- “I'm tired of being the funniest person in the room.” - Del Close
- “Friends applaud, the comedy is finished.” - Beethoven
- “Hey, fellas! How about this for a headline for tomorrow’s paper? French Fries!” - James Donald French
"Good Luck Charlie" star Mia Talerico: what is she up to in 2019?
People die, but their final utterances live on.  From each of the sayings, you can learn a lesson and therefore, do not hesitate to share these famous last words with friends.


Using Sticky Element Script easily
To install the script simply add this line to your head section of your html file
<script src="FOLDER_PATH/stickyelement.min.js"></script>
To initialize sticky element follow these examples:-
To install the script simply add this line to your head section of your html file
<script src="FOLDER_PATH/stickyelement.min.js"></script>
To initialize sticky element follow these examples:-


Contact
Zhiping Shi has been the owner and head teacher of her studio for the past 15 years. Before opening her studio, she learned traditional Chinese dance and ballet for over 25 years. Throughout her career she has taught more than 200 students and has produced. Zhiping is passionate about nurturing her students into skilled, graceful performers.
Zhiping Shi Dance Studio
1264 South Abel Street
Milpitas, CA 95035
408-802-7897
zhipingshidance@gmail.com


|
Max API
8.2.0
|
The patcher. More...
Functions | |
| int | jpatcher_is_patcher (t_object *p) |
| Determine of a t_object* is a patcher object. More... | |
| t_object * | jpatcher_get_box (t_object *p) |
| If a patcher is inside a box, return its box. More... | |
| long | jpatcher_get_count (t_object *p) |
| Determine the number of boxes in a patcher. More... | |
| t_max_err | jpatcher_set_locked (t_object *p, char c) |
| Lock or unlock a patcher. More... | |
| char | jpatcher_get_presentation (t_object *p) |
| Determine whether a patcher is currently in presentation mode. More... | |
| t_max_err | jpatcher_set_presentation (t_object *p, char c) |
| Set a patcher to presentation mode. More... | |
| t_object * | jpatcher_get_firstobject (t_object *p) |
| Get the first box in a patcher. More... | |
| t_object * | jpatcher_get_lastobject (t_object *p) |
| Get the last box in a patcher. More... | |
| t_object * | jpatcher_get_firstline (t_object *p) |
| Get the first line (patch-cord) in a patcher. More... | |
| t_object * | jpatcher_get_firstview (t_object *p) |
| Get the first view (jpatcherview) for a given patcher. More... | |
| t_symbol * | jpatcher_get_title (t_object *p) |
| Retrieve a patcher's title. More... | |
| t_max_err | jpatcher_set_title (t_object *p, t_symbol *ps) |
| Set a patcher's title. More... | |
| t_symbol * | jpatcher_get_name (t_object *p) |
| Retrieve a patcher's name. More... | |
| t_symbol * | jpatcher_get_filepath (t_object *p) |
| Retrieve a patcher's file path. More... | |
| t_symbol * | jpatcher_get_filename (t_object *p) |
| Retrieve a patcher's file name. More... | |
| char | jpatcher_get_dirty (t_object *p) |
| Determine whether a patcher's dirty bit has been set. More... | |
| t_max_err | jpatcher_set_dirty (t_object *p, char c) |
| Set a patcher's dirty bit. More... | |
| char | jpatcher_get_bglocked (t_object *p) |
| Determine whether a patcher's background layer is locked. More... | |
| t_max_err | jpatcher_set_bglocked (t_object *p, char c) |
| Set whether a patcher's background layer is locked. More... | |
| char | jpatcher_get_bghidden (t_object *p) |
| Determine whether a patcher's background layer is hidden. More... | |
| t_max_err | jpatcher_set_bghidden (t_object *p, char c) |
| Set whether a patcher's background layer is hidden. More... | |
| char | jpatcher_get_fghidden (t_object *p) |
| Determine whether a patcher's foreground layer is hidden. More... | |
| t_max_err | jpatcher_set_fghidden (t_object *p, char c) |
| Set whether a patcher's foreground layer is hidden. More... | |
| t_max_err | jpatcher_get_editing_bgcolor (t_object *p, t_jrgba *prgba) |
| Retrieve a patcher's editing background color. More... | |
| t_max_err | jpatcher_set_editing_bgcolor (t_object *p, t_jrgba *prgba) |
| Set a patcher's editing background color. More... | |
| t_max_err | jpatcher_get_bgcolor (t_object *p, t_jrgba *prgba) |
| Retrieve a patcher's unlocked background color. More... | |
| t_max_err | jpatcher_get_locked_bgcolor (t_object *p, t_jrgba *prgba) |
| Retrieve a patcher's locked background color. More... | |
| t_max_err | jpatcher_set_bgcolor (t_object *p, t_jrgba *prgba) |
| Set a patcher's unlocked background color. More... | |
| t_max_err | jpatcher_set_locked_bgcolor (t_object *p, t_jrgba *prgba) |
| Set a patcher's locked background color. More... | |
| t_max_err | jpatcher_get_gridsize (t_object *p, double *gridsizeX, double *gridsizeY) |
| Retrieve a patcher's grid size. More... | |
| t_max_err | jpatcher_set_gridsize (t_object *p, double gridsizeX, double gridsizeY) |
| Set a patcher's grid size. More... | |
| void | jpatcher_deleteobj (t_object *p, t_jbox *b) |
| Delete an object that is in a patcher. More... | |
| t_object * | jpatcher_get_parentpatcher (t_object *p) |
| Given a patcher, return its parent patcher. More... | |
| t_object * | jpatcher_get_toppatcher (t_object *p) |
| Given a patcher, return the top-level patcher for the tree in which it exists. More... | |
| t_object * | jpatcher_get_hubholder (t_object *p) |
| Given a patcher, return the patcher that will be responsible for holding the parameter hub. More... | |
| t_max_err | jpatcher_get_rect (t_object *p, t_rect *pr) |
| Query a patcher to determine its location and size. More... | |
| t_max_err | jpatcher_set_rect (t_object *p, t_rect *pr) |
| Set a patcher's location and size. More... | |
| t_max_err | jpatcher_get_defrect (t_object *p, t_rect *pr) |
| Query a patcher to determine the location and dimensions of its window when initially opened. More... | |
| t_max_err | jpatcher_set_defrect (t_object *p, t_rect *pr) |
| Set a patcher's default location and size. More... | |
| t_symbol * | jpatcher_uniqueboxname (t_object *p, t_symbol *classname) |
| Generate a unique name for a box in patcher. More... | |
| t_symbol * | jpatcher_get_default_fontname (t_object *p) |
| Return the name of the default font used for new objects in a patcher. More... | |
| float | jpatcher_get_default_fontsize (t_object *p) |
| Return the size of the default font used for new objects in a patcher. More... | |
| long | jpatcher_get_default_fontface (t_object *p) |
| Return the index of the default font face used for new objects in a patcher. More... | |
| long | jpatcher_get_fileversion (t_object *p) |
| Return the file version of the patcher. More... | |
| long | jpatcher_get_currentfileversion (void) |
| Return the file version for any new patchers, e.g. More... | |
The patcher.
Delete an object that is in a patcher.
| p | The patcher. |
| b | The object box to delete. |
Retrieve a patcher's unlocked background color.
| p | The patcher to be queried. |
| prgba | The address of a valid t_jrgba struct that will be filled-in with the current patcher color values. |
| char jpatcher_get_bghidden | ( | t_object * | p | ) |
Determine whether a patcher's background layer is hidden.
| p | The patcher to be queried. |
| char jpatcher_get_bglocked | ( | t_object * | p | ) |
Determine whether a patcher's background layer is locked.
| p | The patcher to be queried. |
If a patcher is inside a box, return its box.
| p | The patcher to be queried. |
| long jpatcher_get_count | ( | t_object * | p | ) |
Determine the number of boxes in a patcher.
| p | The patcher to be queried. |
| long jpatcher_get_currentfileversion | ( | void | ) |
Return the file version for any new patchers, e.g.
the current version created by Max.
| long jpatcher_get_default_fontface | ( | t_object * | p | ) |
Return the index of the default font face used for new objects in a patcher.
| p | A pointer to a patcher instance. |
Return the name of the default font used for new objects in a patcher.
| p | A pointer to a patcher instance. |
| float jpatcher_get_default_fontsize | ( | t_object * | p | ) |
Return the size of the default font used for new objects in a patcher.
| p | A pointer to a patcher instance. |
Query a patcher to determine the location and dimensions of its window when initially opened.
| p | A pointer to a patcher instance. |
| pr | The address of valid t_rect whose values will be filled-in upon return. |
| char jpatcher_get_dirty | ( | t_object * | p | ) |
Determine whether a patcher's dirty bit has been set.
| p | The patcher to be queried. |
Retrieve a patcher's editing background color.
| p | The patcher to be queried. |
| prgba | The address of a valid t_jrgba struct that will be filled-in with the current patcher color values. |
| char jpatcher_get_fghidden | ( | t_object * | p | ) |
Determine whether a patcher's foreground layer is hidden.
| p | The patcher to be queried. |
Retrieve a patcher's file name.
| p | The patcher to be queried. |
Retrieve a patcher's file path.
| p | The patcher to be queried. |
| long jpatcher_get_fileversion | ( | t_object * | p | ) |
Return the file version of the patcher.
| p | A pointer to the patcher whose version number is desired. |
Get the first line (patch-cord) in a patcher.
All lines in a patcher are maintained internally in a t_linklist. Use this function to begin traversing a patcher's lines.
| p | The patcher to be queried. |
Get the first box in a patcher.
All boxes in a patcher are maintained internally in a t_linklist. Use this function together with jbox_get_nextobject() to traverse a patcher.
| p | The patcher to be queried. |
Get the first view (jpatcherview) for a given patcher.
All views of a patcher are maintained internally as a t_linklist. Use this function to begin traversing a patcher's views.
| p | The patcher to be queried. |
Retrieve a patcher's grid size.
| p | The patcher to be queried. |
| gridsizeX | The address of a double that will be set to the current horizontal grid spacing for the patcher. |
| gridsizeY | The address of a double that will be set to the current vertical grid spacing for the patcher. |
Given a patcher, return the patcher that will be responsible for holding the parameter hub.
| p | The patcher to be queried. |
Get the last box in a patcher.
All boxes in a patcher are maintained internally in a t_linklist. Use this function together with jbox_get_prevobject() to traverse a patcher.
| p | The patcher to be queried. |
Retrieve a patcher's locked background color.
| p | The patcher to be queried. |
| prgba | The address of a valid t_jrgba struct that will be filled-in with the current patcher color values. |
Retrieve a patcher's name.
| p | The patcher to be queried. |
Given a patcher, return its parent patcher.
| p | The patcher to be queried. |
| char jpatcher_get_presentation | ( | t_object * | p | ) |
Determine whether a patcher is currently in presentation mode.
| p | The patcher to be queried. |
Query a patcher to determine its location and size.
| p | A pointer to a patcher instance. |
| pr | The address of valid t_rect whose values will be filled-in upon return. |
Retrieve a patcher's title.
| p | The patcher to be queried. |
Given a patcher, return the top-level patcher for the tree in which it exists.
| p | The patcher to be queried. |
| int jpatcher_is_patcher | ( | t_object * | p | ) |
Determine of a t_object* is a patcher object.
| p | The object pointer to test. |
Set a patcher's unlocked background color.
| p | The patcher to be queried. |
| prgba | The address of a t_jrgba struct containing the new color to use. |
Set whether a patcher's background layer is hidden.
| p | The patcher whose dirty bit will be set. |
| c | Pass true to hide the patcher's background layer, otherwise pass false. |
Set whether a patcher's background layer is locked.
| p | The patcher whose dirty bit will be set. |
| c | Pass true to lock the patcher's background layer, otherwise pass false. |
Set a patcher's default location and size.
| p | A pointer to a patcher instance. |
| pr | The address of a t_rect with the new position and size. |
Set a patcher's dirty bit.
| p | The patcher whose dirty bit will be set. |
| c | The new value for the patcher's dirty bit (pass true or false). |
Set a patcher's editing background color.
| p | The patcher to be queried. |
| prgba | The address of a t_jrgba struct containing the new color to use. |
Set whether a patcher's foreground layer is hidden.
| p | The patcher whose dirty bit will be set. |
| c | Pass true to hide the patcher's foreground layer, otherwise pass false. |
Set a patcher's grid size.
| p | The patcher to be queried. |
| gridsizeX | The new horizontal grid spacing for the patcher. |
| gridsizeY | The new vertical grid spacing for the patcher. |
Lock or unlock a patcher.
| p | The patcher whose locked state will be changed. |
| c | Pass true to lock a patcher, otherwise pass false. |
Set a patcher's locked background color.
| p | The patcher to be queried. |
| prgba | The address of a t_jrgba struct containing the new color to use. |
Set a patcher to presentation mode.
| p | The patcher whose locked state will be changed. |
| c | Pass true to switch the patcher to presentation mode, otherwise pass false. |
Set a patcher's location and size.
| p | A pointer to a patcher instance. |
| pr | The address of a t_rect with the new position and size. |
Set a patcher's title.
| p | The patcher whose locked state will be changed. |
| ps | The new title for the patcher. |
Generate a unique name for a box in patcher.
| p | A pointer to a patcher instance. |
| classname | The name of an object's class. |


Address: Enter the first part of the address. Ex: for 700 North Tryon Street, try 700 n
Place or Street: Enter any part of a place or street name. Ex: type carolina
Intersection: Enter a street name, followed by an &. Ex: type ruth &
Parcel ID: Enter an 8-digit Parcel ID. Ex: type 11111111
Find My Location: If your web browser supports geolocation, you will see Find My Location under the search bar. Your browser will ask you for permission to use this feature the first time it is activated.
GeoPortal is an advanced web mapping system created by Mecklenburg County GIS. Its mission is to be an easy to use "portal" into Mecklenburg County's data and services. This site is powered by free and open source software. The source code for this site is released under the MIT free software license and can be downloaded here.
This system is subject to current public information rules and regulations. Information presented on this web site is considered public information and may be distributed or copied. Mecklenburg County and its data providers give no warranty, expressed or implied, as to the accuracy, precision, timeliness, completeness, or any other aspect of the data presented. The publisher and data providers assume no liability for damage arrising from the use of this web site or the data provided herein.
Click on the map to set the center of the buffer and draw the buffer on the map.


Awesome headline
Some description goes here.
Sign In Here
Don't have an account? Sign up here!
Full Name
Email
This is a hint message, this is how you do it.
Confirm Email
Something Else
This is a hint message, this is how you do it.
I accept the
Terms
and
Privacy Policy
.
Register New Account


Card title
Title:
Peace Sells
Artist:
Megadeth
Media link (maybe an href?)
User's comment will go here


The only way to know if you have chlamydia is to get tested. You might have no symptoms.
You might be told to get tested 2 weeks after unprotected sex. This is because it can take 2 weeks for chlamydia to show up in a test.
Samples will be taken from the areas that might be infected using one or more of the following methods:
Your samples will be sent to a lab and tested for chlamydia. You'll get your results by phone or text message.
If you see a health professional they'll also ask questions about your sexual activity and symptoms. This will help them decide what samples to take.
The best ways to get tested for chlamydia are to:


Sorry - there was a problem saving your book details. Please try again later.
Book details saved as requested.
Unable to get the details for the request book. Please try later.
Book details updated as requested.
Unable to update the book. Please try later.
It looks as though there was HTML entered into the {{htmlErrorField}} field - please remove it and try again.


443. String Compression
Difficulty: Easy
Topics: Array
Given an array of characters, compress it .
The length after compression must always be smaller than or equal to the original array.
Every element of the array should be a character (not int) of length 1.
After you are done modifying the input array , return the new length of the array.
Follow up:
Could you solve it using only O(1) extra space?
Example 1:
Input:
["a","a","b","b","c","c","c"]
Output:
Return 6, and the first 6 characters of the input array should be: ["a","2","b","2","c","3"]
Explanation:
"aa" is replaced by "a2". "bb" is replaced by "b2". "ccc" is replaced by "c3".
Example 2:
Input:
["a"]
Output:
Return 1, and the first 1 characters of the input array should be: ["a"]
Explanation:
Nothing is replaced.
Example 3:
Input:
["a","b","b","b","b","b","b","b","b","b","b","b","b"]
Output:
Return 4, and the first 4 characters of the input array should be: ["a","b","1","2"].
Explanation:
Since the character "a" does not repeat, it is not compressed. "bbbbbbbbbbbb" is replaced by "b12".
Notice each digit has it's own entry in the array.
Note:
- All characters have an ASCII value in
[35, 126]
. 1 <= len(chars) <= 1000
.
Solution
Language: Python
class Solution(object):
def compress(self, chars):
"""
:type chars: List[str]
:rtype: int
"""
l, r = 0, 0
while r < len(chars):
c = chars[r]
cnt = 0
while r < len(chars) and chars[r] == c:
r += 1
cnt += 1
chars[l] = c
l += 1
if cnt > 1:
for d in str(cnt):
chars[l] = d
l += 1
return l
Notes
- two pointers
- First, check
r < len(chars)
to avoid out of index range


Open color is a color scheme for UI design. You can use it for font, background, border, etc. It contains a gray and twelve colors. Open color is provided as CSS, SCSS, LESS, Stylus, Adobe library, Photoshop/Illustrator swatches and Sketch palette.
* All the color is tested on deuteranopia and protanopia mode. The process will soon be published in the article.Check out the list below.
open-color.json
$ npm run compile-templates
docs/asset/download/open-color_*.*.*.aco
package.json
docs/asset/download/open-color_*.*.*.aco
README.md
docs/documents.html
README.md
docs/_includes/introduction.html
docs/documents.html


SaveManager Class
Is responsible for the storage and management of the various ways a Developer can save game information. This is useful as in the future there will be a variety of different ways/locations you can save information in. Example: You may want to save information locally so you would use the localStorage area on this saveManager but if you wanted the information saved on a server then you would use a different 'plugin' that would save it onto a server.
Constructor
SaveManager
-
game
Parameters:
-
game
Game
Returns:
SaveManager
Item Index
Properties
- current
- game
- LOCAL_STORAGE static
- localStorage
Methods
add
-
key
-
data
-
save
Returns add method on the current saving method that is being used.
Parameters:
-
key
String -
data
Any -
save
Boolean
Returns:
boot
()
protected
The boot method for this SaveManager is executed when the game is in the process of starting up. This is an internal method used by Kiwi and as such a Dev should not need to use it.
edit
-
key
-
data
-
save
Returns edit method on the current saving method that is being used.
Parameters:
-
key
String -
data
Any -
save
Boolean
Returns:
exists
()
Boolean
public
Returns the exists method on the current saving method that is being used.
Returns:
getData
-
key
Returns getData method on the current saving method that is being used.
Parameters:
-
key
String
Returns:
objType
()
public
Returns the type of object that this is.
Returns:
string
remove
-
key
-
save
Returns remove method on the current saving method that is being used.
Parameters:
-
key
String -
save
Boolean
Returns:
save
()
Boolean
public
Returns save method on the current saving method that is being used.
Returns:
switchCurrent
-
type
Switches the current method of saving that being used to a different one based on the type passed.
Parameters:
-
type
Number
Properties
current
Unknown
public
Refer's to the current saving 'method' that is being. More useful if you have multiple different ways of saving information and you want to switch between them.
game
Game
public
The game that this SaveManager belongs to.
LOCAL_STORAGE
Number
public
static
A Static property with the number associated with the used of localstorage method.
Default: 1
localStorage
Unknown
public
Contains the object that handles localStorage saving of data for this game.


Random selection players playing 6 rounds of zolīte game. Katniss sorts her cards by strength every time. We get to see Rob's cards, too. See the console for JSON result.
Choose "Human" for Katniss if you wish to play yourself.
The visual representation by Einar Egilsson's "cards.js" library.


--- layout: post title: "Widescreen hack for Yojimbo 2" external-url: http://hicksdesign.co.uk/journal/widescreen-hack-for-yojimbo-2 ---
Makes Yojimbo usable again. Thank you Mr Hicks.


Relax, this shouldn't be too bad. As a self proclaimed bad test taker, I understand the
anxiety around taking tests. As such, this is a painless process with basic questions on html, css,
javascript and other basic coding concepts. I hope you are able to enjoy it.
Before you begin, a few things to note.


We're sorry but yy-folium doesn't work properly without JavaScript enabled. Please enable it to continue.


---
title: "ARBOR DAY CELEBRATION"
date: "2000-01-01 21:04:30 -06:00"
categories:
- spring
- free
subtitle: "ZAP Free Admission Day"
layout: "free-events"
event-image: "arbor-day-oak-tunnel.jpg"
event-dates: "April 30"
event-location: "Red Butte Garden"
button-type: "register"
tickets-link: ""
registration-info: "Questions?
Please call<PHONE_NUMBER>"
instructor-info: ""
member-cost: "Free"
public-cost: "Free"
event-notes: ""
tickets-button: "hide"
refund-policy: "hide"
published: true
---
As part of Utah’s official arboretum, there’s no place better than Red Butte Garden to celebrate Arbor Day!
Join us for a day filled with "tree-rific" fun and discover the vital role trees play not only in our lives, but also in the natural world.
Thanks to funding in part by Salt Lake County Zoo, Arts, and Parks Program (ZAP) Arbor Day is a ZAP Free Day!
Enjoy free Garden admission all day.
Garden Members get a year of admission to the Garden, as well as discounts on classes, concert tickets, summer camps, special events, and more!
Special thanks to Salt Lake County Zoo, Arts and Parks (ZAP) Program for making free Garden admission days possible.
Click HERE for more Red Butte Garden free event information.


{% from 'include/input_macros.html' import input %}
Enter password and confirm
Passwords are mismatched


{c,transferCard,transferCardToTop} = require './cards' if exports?
This “indecisive import” pattern is messy but it gets the job done, and it’s explained at the bottom of this documentation.
{c,transferCard,transferCardToTop} = require './cards' if exports?
A PlayerState stores the part of the game state that is specific to each player, plus what AI is making the decisions.
class PlayerState
At the start of the game, the State should .initialize() each PlayerState, which assigns its AI and sets up its starting state. Before then, it is an empty object.
initialize: (ai, logFunc) ->
These attributes of the PlayerState are okay for card effects and AI strategies to refer to.
Often, you will want to find out something
about the player whose turn it is, who will appear as state.current
.
For example, if you want to know how many actions the current player
has, you can look up state.current.actions
.
@actions = 1
@buys = 1
@coins = 0
@potions = 0
@coinTokens = 0
@coinTokensSpendThisTurn = 0
@multipliedDurations = []
@chips = 0
@hand = []
@discard = [c.Copper, c.Copper, c.Copper, c.Copper, c.Copper,
c.Copper, c.Copper, c.Estate, c.Estate, c.Estate]
A mat is a place where cards can store inter-turn state for a player. It can correspond to a physical mat, like the Island or Pirate Ship Mat or just a place to set things aside for cards like Haven.
@mats = {}
If you want to ask what’s in a player’s draw pile, be sure to only do
it to a hypothetical PlayerState that you retrieve with
state.hypothetical(ai)
. Then the draw pile will contain a random
guess, as opposed to the actual hidden information.
@draw = []
@inPlay = []
@duration = []
@setAside = []
@gainedThisTurn = []
@turnsTaken = 0
To stack various card effects, we’ll have to keep track of the location of the card we’re playing and the card we’re gaining. For example, if you have two Feasts in hand and you Throne Room a Feast, you don’t trash both Feasts — you trash one and then do nothing, based on the fact that that particular Feast is already in the trash.
@playLocation = 'inPlay'
@gainLocation = 'discard'
The actionStack
is not a physical location for cards to be in; it’s
a computational list of what actions are in play but not yet resolved.
This becomes particularly important with King’s Courts.
@actionStack = []
Set the properties passed in from the State.
@ai = ai
@logFunc = logFunc
To start the game, the player starts with the 10 starting cards in the discard pile, then shuffles them and draws 5.
this.drawCards(5)
this
The methods here ask about general properties of a player’s deck,
discard pile, and so on. A number of similar methods appear on the State
class defined below, which deal with information that is not so
player-specific, such as the cards in the supply.
As an example:
Most AI code will start with a reference to the State, called state
.
If you want to check the number of cards in the current player’s deck,
you would ask the player object state.current
:
state.current.numCardsInDeck()
If you want to check how many piles are currently empty, you would ask the state object itself:
state.numEmptyPiles()
getDeck()
returns all the cards in the player’s deck, even those in
strange places such as the Island mat.
getDeck: () ->
result = [].concat(@draw, @discard, @hand, @inPlay, @duration, @setAside)
for own name, contents of @mats when contents?
If contents is a card or an array containing cards, add it to the list
if contents.hasOwnProperty('playEffect') || contents[0]?.hasOwnProperty('playEffect')
result = result.concat(contents)
result
getCurrentAction()
returns the action being resolved that is on the
top of the stack.
getCurrentAction: () ->
<EMAIL_ADDRESS>- 1]
getMultiplier()
gets the value of the multipier that is currently being
played: 1 in most cases, 2 after playing Throne Room, 3 after playing
King’s Court.
getMultiplier: () ->
action = this.getCurrentAction()
if action?
return action.getMultiplier()
else
return 1
countInDeck(card)
counts the number of copies of a card in the deck.
The card may be specified either by name or as a card object.
countInDeck: (card) ->
count = 0
for card2 in this.getDeck()
if card.toString() == card2.toString()
count++
count
numCardsInDeck()
returns the size of the player’s deck.
numCardsInDeck: () -> this.getDeck().length
Aliases for numCardsInDeck
that you might use intuitively.
countCardsInDeck: this.numCardsInDeck
cardsInDeck: this.numCardsInDeck
countCardTypeInDeck(type)
counts the number of cards of a given type
in the deck. Curse is not a type for these purposes, it’s a card.
countCardTypeInDeck: (type) ->
typeChecker = 'is'+type
count = 0
for card in this.getDeck()
if card[typeChecker]
count++
count
numCardTypeInDeck: this.countCardTypeInDeck
getVP()
returns the number of VP the player would have if the game
ended now.
getVP: (state) ->
total = @chips
for card in this.getDeck()
total += card.getVP(this)
total
countVP: this.getVP
getTotalMoney()
adds up the total money in the player’s deck,
including both Treasure and +$x, +y Actions cards.
getTotalMoney: () ->
total = 0
for card in this.getDeck()
if card.isTreasure or card.actions >= 1
total += card.coins
total += card.coinTokens
total
totalMoney: this.getTotalMoney
getAvailableMoney()
counts the money the player might have upon playing
all treasure in hand. Banks, Ventures, and such are counted inaccurately
so far.
getAvailableMoney: () ->
this.coins + this.getTreasureInHand()
availableMoney: this.getAvailableMoney
getTreasureInHand()
adds up the value of the treasure in the player’s
hand. Banks and Ventures and such will be inaccurate.
A getMoneyInHand(state)
method that counted playable action cards would
be great, but I’m skipping it for now because it’s difficult to get right.
getTreasureInHand: () ->
total = 0
for card in this.hand
if card.isTreasure
total += card.coins
total
treasureInHand: this.getTreasureInHand
countPlayableTerminals: (state) ->
if (@actions>0)
@actions + ( (Math.max (card.getActions(state) - 1), 0 for card in this.hand).reduce (s,t) -> s + t)
else 0
numPlayableTerminals: this.countPlayableTerminals
playableTerminals: this.countPlayableTerminals
countInHand(card)
counts the number of copies of a card in hand.
countInHand: (card) ->
countStr(@hand, card)
countInDiscard(card)
counts the number of copies of a card in the discard
pile.
countInDiscard: (card) ->
countStr(@discard, card)
countInPlay(card)
counts the number of copies of a card in play. Don’t use this
for evaluating effects that stack, because you may also need
to take Throne Rooms and King’s Courts into account.
countInPlay: (card) ->
countStr(@inPlay, card)
numActionCardsInDeck()
is the number of action cards in the player’s
entire deck.
numActionCardsInDeck: () ->
this.countCardTypeInDeck('Action')
getActionDensity()
returns a fractional value, between 0.0 and 1.0,
representing the proportion of actions in the deck.
getActionDensity: () ->
this.numActionCardsInDeck() / this.getDeck().length
menagerieDraws()
is the number of cards the player would draw upon
playing a Menagerie: either 1 or 3.
TODO: allow for a hypothetical version where it’s okay to have another Menagerie.
menagerieDraws: () ->
seen = {}
cardsToDraw = 3
for card in @hand
if seen[card.name]?
cardsToDraw = 1
break
seen[card.name] = true
cardsToDraw
shantyTownDraws()
is the number of cards the player draws upon
playing a Shanty town: either 0 or 2.
Set hypothetical
to true
if deciding whether to play a Shanty Town
(because it won’t be in your hand anymore when you do).
shantyTownDraws: (hypothetical = false) ->
cardsToDraw = 2
skippedShanty = false
for card in @hand
if card.isAction
if hypothetical and not skippedShanty
skippedShanty = true
else
cardsToDraw = 0
break
cardsToDraw
actionBalance()
is a complex method meant to be used by AIs in
deciding whether they want +actions or +cards, for example.
If the actionBalance is less than 0, you want +actions, because otherwise you will have dead action cards in hand or risk drawing them dead. If it is greater than 0, you want +cards, because you have a surplus of actions and need action cards to spend them on.
actionBalance: () ->
balance = @actions
for card in @hand
if card.isAction
balance += card.actions
balance--
Estimate the risk of drawing an action card dead.
TODO: do something better when there are variable card-drawers.
if card.actions == 0
balance -= card.cards * this.getActionDensity()
balance
deckActionBalance()
is a measure of action balance across the entire
deck.
deckActionBalance: () ->
balance = 0
for card in this.getDeck()
if card.isAction
balance += card.actions
balance--
return balance / this.numCardsInDeck()
What is the trashing power of this hand?
trashingInHand: () ->
trash = 0
for card in this.hand
Count actions that simply trash a constant number of cards from hand.
trash += card.trash
Add other trashers, including the trash-on-gain power of Watchtower.
trash += 2 if card is c.Steward
trash += 2 if card is c['Trading Post']
trash += 4 if card is c.Chapel
trash += 1 if card is c.Masquerade
trash += 2 if card is c.Ambassador
trash += 1 if card is c.Watchtower
return trash
numUniqueCardsInPlay: () ->
unique = []
cards = @inPlay.concat(@duration)
for card in cards
if card not in unique
unique.push(card)
return unique.length
countUniqueCardsInPlay: this.numUniqueCardsInPlay
uniqueCardsInPlay: this.numUniqueCardsInPlay
drawCards: (nCards) ->
drawn = this.getCardsFromDeck(nCards)
Array::push.apply @hand, drawn
this.log("#{@ai} draws #{drawn.length} cards: #{drawn}.")
return drawn
getCardsFromDeck
is a sub-method of many things that need to happen
with the game. It takes nCards
cards off the deck, and then
returns them so you can do something with them.
Code that calls getCardsFromDeck
is responsible for making sure the cards aren’t just “dropped on the
floor” after that, so to speak.
getCardsFromDeck: (nCards) ->
if @draw.length < nCards
diff = nCards - @draw.length
drawn = @draw.slice(0)
@draw = []
if @discard.length > 0
this.shuffle()
return drawn.concat(this.getCardsFromDeck(diff))
else
return drawn
else
drawn = @draw[0...nCards]
@draw = @draw[nCards...]
return drawn
dig
is a function to draw and reveal cards from the deck until
certain ones are found. The cards to be found are defined by digFunc,
which takes (state, card) and returns true if card is one that we’re
trying find. For example, Venture’s and Adventurer’s would be
digFunc: (state, card) -> card.isTreasure
nCards is the number of cards we’re looking for; usually 1, but Golem and Adventurer look for 2 cards.
By default, discard the revealed and set aside cards, but Scrying Pool digs for a card that is not an action, then draws up all the revealed actions as well; discardSetAside allows a card calling dig to do something with setAside other than discarding.
dig: (state, digFunc, nCards=1, discardSetAside=true) ->
foundCards = [] # These are the cards you're looking for
revealedCards = [] # All the cards drawn and revealed from the deck
while foundCards.length < nCards
drawn = this.getCardsFromDeck(1)
break if drawn.length == 0
card = drawn[0]
revealedCards.push(card)
if digFunc(state, card)
foundCards.push(card)
else
this.setAside.push(card)
if revealedCards.length == 0
this.log("...#{this.ai} has no cards to draw.")
else
this.log("...#{this.ai} reveals #{revealedCards}.")
if discardSetAside
if this.setAside.length > 0
this.log("...#{this.ai} discards #{this.setAside}.")
this.discard = this.discard.concat(this.setAside)
state.handleDiscards(this, this.setAside)
this.setAside = []
foundCards
discardFromDeck: (nCards) ->
throw new Error("discardFromDeck is done by the state now")
doDiscard: (card) ->
throw new Error("doDiscard is done by the state now")
doTrash: (card) ->
throw new Error("doTrash is done by the state now")
doPutOnDeck: (card) ->
throw new Error("doPutOnDeck is done by the state now")
shuffle: () ->
this.log("(#{@ai} shuffles.)")
if @draw.length > 0
throw new Error("Shuffling while there are cards left to draw")
shuffle(@discard)
@draw = @discard
@discard = []
TODO: add an AI decision for Stashes
Most PlayerStates are created by copying an existing one.
copy: () ->
other = new PlayerState()
other.actions = @actions
other.buys = @buys
other.coins = @coins
other.potions = @potions
other.coinTokens = @coinTokens
other.multipliedDurations = @multipliedDurations.slice(0)
Clone mat contents, deep-copying arrays of cards
other.mats = {}
for own name, contents of @mats
if contents instanceof Array
contents = contents.concat()
other.mats[name] = contents
other.chips = @chips
other.hand = @hand.slice(0)
other.draw = @draw.slice(0)
other.discard = @discard.slice(0)
other.inPlay = @inPlay.slice(0)
other.duration = @duration.slice(0)
other.setAside = @setAside.slice(0)
other.gainedThisTurn = @gainedThisTurn.slice(0)
other.playLocation = @playLocation
other.gainLocation = @gainLocation
other.actionStack = @actionStack.slice(0)
other.actionsPlayed = @actionsPlayed
other.ai = @ai
other.logFunc = @logFunc
other.turnsTaken = @turnsTaken
other.coinTokensSpendThisTurn = @coinTokensSpendThisTurn
other
Games can provide output using the log
function.
log: (obj) ->
if this.logFunc?
this.logFunc(obj)
else
if console?
console.log(obj)
A State instance stores the complete state of the game at a point in time.
Almost all operations work by changing the game state. This means that if AI code wants to evaluate potential decisions, it should do them using a copy of the state (often one with hidden information in it).
class State
basicSupply: [c.Curse, c.Copper, c.Silver, c.Gold,
c.Estate, c.Duchy, c.Province]
extraSupply: [c.Potion, c.Platinum, c.Colony]
AIs can get at the c
object that stores information about cards
by looking up state.cardInfo
.
cardInfo: c
Set up the state at the start of the game. Takes these arguments:
ais
: a list of AI objects that will make the decisions, one per player.
This sets the number of players in the game.tableau
: the list of non-basic cards in the supply. Colony, Platinum,
and Potion have to be listed explicitly. initialize: (ais, tableau, logFunc) ->
this.logFunc = logFunc
@players = (new PlayerState().initialize(ai, this.logFunc) for ai in ais)
@players = []
playerNum = 0
for ai in ais
playerNum += 1 if ai.name[2] == ‘:’ ai.name = ai.name[3…] ai.name = “P#{playerNum}:#{ai.name}”
player = new PlayerState().initialize(ai, this.logFunc)
@players.push(player)
@nPlayers = @players.length
@current = @players[0]
@supply = this.makeSupply(tableau)
Cards like Tournament or Black Market may put cards in a special supply
@specialSupply = {}
@trash = []
A map of Card to state object that allows cards to define lasting state.
@cardState = {}
A list of objects which have a “modify” method that takes a card and returns a modification to its cost. Objects must also have a “source” property that specifies which card caused the cost modification.
@costModifiers = []
@copperValue = 1
@phase = 'start'
@extraturn = false
@cache = {}
The depth
indicates how deep into hypothetical situations we are. A depth of 0
indicates the state of the actual game.
@depth = 0
this.log("Tableau: #{tableau}")
Let cards in the tableau know the game is starting so they can perform any necessary initialization
for card in tableau
card.startGameEffect(this)
totalCards
tracks the total number of cards that are in the game.
It takes two arguments, ais
and options
. ais
is the list of AI objects, and
options
is an object with these keys and values:
randomizeOrder
: whether to shuffle the player order. Defaults to true.colonies
: whether to add Colonies and Platinums to the tableau. Defaults
to false-ish: it can be set to true by a strategy that requires Colony if
left undefined. setUpWithOptions: (ais, options) ->
tableau = []
if options.require?
for card in options.require
tableau.push(c[card])
for ai in ais
if ai.requires?
for card in ai.requires
card = c[card]
if card in [c.Colony, c.Platinum]
if not options.colonies?
options.colonies = true
else if options.colonies is false
throw new Error("This setup forbids Colonies, but #{ai} requires them")
else if card not in tableau and card not in this.basicSupply\
and card not in this.extraSupply and not card.isPrize
tableau.push(card)
if tableau.length > 10
throw new Error("These strategies require too many different cards to play against each other.")
index = 0
moreCards = c.allCards.slice(0)
shuffle(moreCards)
while tableau.length < 10
card = c[moreCards[index]]
if not (card in tableau or card in this.basicSupply or card in this.extraSupply or card.isPrize)
tableau.push(card)
index++
if options.colonies
tableau.push(c.Colony)
tableau.push(c.Platinum)
for card in tableau
if card.costPotion > 0
if c.Potion not in tableau
tableau.push(c.Potion)
if options.randomizeOrder
shuffle(ais)
return this.initialize(ais, tableau, options.log ? console.log)
Given the tableau (the set of non-basic cards in play), construct the appropriate supply for the number of players.
makeSupply: (tableau) ->
allCards = this.basicSupply.concat(tableau)
supply = {}
for card in allCards
if c[card].startingSupply(this) > 0
card = c[card] ? card
supply[card] = card.startingSupply(this)
supply
These methods are referred to by some card effects, but can also be useful in crafting a strategy.
emptyPiles()
determines which supply piles are empty.
emptyPiles: () ->
piles = []
for key, value of @supply
if value == 0
piles.push(key)
piles
numEmptyPiles()
simply returns the number of empty piles.
numEmptyPiles: () ->
this.emptyPiles().length
filledPiles()
determines which supply piles are not empty.
filledPiles: () ->
piles = []
for key, value of @supply
if value > 0
piles.push(key)
piles
gameIsOver()
returns whether the game is over.
gameIsOver: () ->
The game can only end after a player has taken a full turn. Check that
by making sure the phase is 'start'
.
return false if @phase != 'start'
Check all the conditions in which empty piles can end the game. Add a fake game-ending condition, too, which is a stalemate the SillyAI sometimes ends up in.
emptyPiles = this.emptyPiles()
if emptyPiles.length >= this.totalPilesToEndGame() \
or (@nPlayers < 5 and emptyPiles.length >= 3) \
or 'Province' in emptyPiles \
or 'Colony' in emptyPiles \
or ('Curse' in emptyPiles and 'Copper' in emptyPiles and @current.turnsTaken >= 100)
this.log("Empty piles: #{emptyPiles}")
for [playerName, vp, turns] in this.getFinalStatus()
this.log("#{playerName} took #{turns} turns and scored #{vp} points.")
return true
return false
getFinalStatus()
is a useful thing to call when gameIsOver()
is true.
It returns a list of triples of [player name, score, turns taken].
getFinalStatus: () ->
([player.ai.toString(), player.getVP(this), player.turnsTaken] for player in @players)
getWinners()
returns a list (usually of length 1) of the names of players
that won the game, or would win if it were over now.
getWinners: () ->
scores = this.getFinalStatus()
best = []
bestScore = -Infinity
for [player, score, turns] in scores
Modify the score by subtracting a fraction of turnsTaken.
modScore = score - turns/100
if modScore == bestScore
best.push(player)
if modScore > bestScore
best = [player]
bestScore = modScore
best
countInSupply()
returns the number of copies of a card that remain
in the supply. It can take in either a card object or card name.
If the card has never been in the supply, it returns 0,
so it is safe to refer to state.countInSupply('Colony')
even in
a non-Colony game. This does not count as an empty pile, of course.
countInSupply: (card) ->
@supply[card] ? 0
totalPilesToEndGame()
returns the number of empty piles that triggers
the end of the game, which is almost always 3.
totalPilesToEndGame: () ->
switch @nPlayers
when 1, 2, 3, 4 then 3
else 4
As a useful heuristic, gainsToEndGame()
returns the minimum number of
buys/gains that would have to be used by an opponent who is determined to
end the game. A low number means the game is probably ending soon.
gainsToEndGame: () ->
if @cache.gainsToEndGame?
return @cache.gainsToEndGame
counts = (count for card, count of @supply)
numericSort(counts)
First, add up the smallest 3 (or 4) piles.
piles = this.totalPilesToEndGame()
minimum = 0
for count in counts[...piles]
minimum += count
Then compare this to the number of Provinces or possibly Colonies remaining, and see which one is smallest.
minimum = Math.min(minimum, @supply['Province'])
if @supply['Colony']?
minimum = Math.min(minimum, @supply['Colony'])
Cache the result; apparently it’s expensive to compute.
@cache.gainsToEndGame = minimum
minimum
smugglerChoices
determines the set of cards that could be gained with a
Smuggler.
smugglerChoices: () ->
choices = [null]
prevPlayer = @players[@nPlayers - 1]
for card in prevPlayer.gainedThisTurn
[coins, potions] = card.getCost(this)
if potions == 0 and coins <= 6
choices.push(card)
choices
countTotalCards
counts the number of cards that exist anywhere.
countTotalCards: () ->
total = 0
for player in @players
total += player.numCardsInDeck()
for card, count of @supply
total += count
for card, count of @specialSupply
total += count
total += @trash.length
total
buyCausesToLose: (player, state, card) ->
if not card? || @supply[card] > 1 || state.gainsToEndGame() > 1
return false
Check to see if the player would be in the lead after buying this card
maxOpponentScore = -Infinity
for status in this.getFinalStatus()
[name, score, turns] = status
if name == player.ai.toString()
myScore = score + card.getVP(player)
else if score > maxOpponentScore
maxOpponentScore = score
if myScore > maxOpponentScore
return false
One level of recursion is enough for first
if (this.depth==0)
[hypState, hypMy] = state.hypothetical(player.ai)
else
return false
try to buy this card C&P from below
[coinCost, potionCost] = card.getCost(this)
hypMy.coins -= coinCost
hypMy.potions -= potionCost
hypMy.buys -= 1
hypState.gainCard(hypMy, card, 'discard', true)
card.onBuy(hypState)
for i in [hypMy.inPlay.length-1...-1]
cardInPlay = hypMy.inPlay[i]
if cardInPlay?
cardInPlay.buyInPlayEffect(hypState, card)
goonses = hypMy.countInPlay('Goons')
if goonses > 0
this.log("...gaining #{goonses} VP.")
hypMy.chips += goonses
C&P until here
finish buyPhase
hypState.doBuyPhase()
find out if game ended and who if we have won it
hypState.phase = 'start'
if not hypState.gameIsOver()
return false
if ( hypMy.ai.toString() in hypState.getWinners() )
return false
state.log("Buying #{card} will cause #{player.ai} to lose the game")
return true
doPlay
performs the next step of the game, which is a particular phase
of a particular player’s turn. If the phase is…
To play the entire game, iterate doPlay()
until gameIsOver()
. Putting
this in a single loop would be a bad idea because it would make Web
browsers freeze up. Browser-facing code should return control after each
call to doPlay()
.
doPlay: () ->
switch @phase
when 'start'
if not @extraturn
@current.turnsTaken += 1
this.log("\n==<EMAIL_ADDRESS>turn<EMAIL_ADDRESS>==")
this.doDurationPhase()
@phase = 'action'
else
this.log("\n==<EMAIL_ADDRESS>turn<EMAIL_ADDRESS>==")
this.doDurationPhase()
@phase = 'action'
when 'action'
this.doActionPhase()
@phase = 'treasure'
when 'treasure'
this.doTreasurePhase()
@phase = 'buy'
when 'buy'
this.doBuyPhase()
@phase = 'cleanup'
when 'cleanup'
this.doCleanupPhase()
if not @extraturn
this.rotatePlayer()
else
@phase = 'start'
@current.duration
contains all cards that are in play with duration
effects. At the start of the turn, check all of these cards and run their
onDuration
method.
doDurationPhase: () ->
Clear out the list of cards gained. (We clear it here because this information is actually used by Smugglers.)
@current.gainedThisTurn = []
iterate backwards because cards might move
for i in<EMAIL_ADDRESS>card = @current.duration[i]
<EMAIL_ADDRESS>resolves the duration effect of #{card}.")
card.onDuration(this)
@current.multipliedDurations
contains virtual copies of cards, which
exist because a multiplier was played on a Duration card.
for card in @current.multipliedDurations
<EMAIL_ADDRESS>resolves the duration effect of #{card} again.")
card.onDuration(this)
@current.multipliedDurations = []
Perform the action phase. Ask the AI repeatedly which action to play,
until there are no more action cards to play or there are no
actions remaining to play them with, or the AI chooses null
, indicating
that it doesn’t want to play an action.
doActionPhase: () ->
while @current.actions > 0
validActions = [null]
Determine the set of unique actions that may be played.
for card in @current.hand
if card.isAction and card not in validActions
validActions.push(card)
Ask the AI for its choice.
action = @current.ai.chooseAction(this, validActions)
return if action is null
Remove the action from the hand and put it in the play area.
if action not in @current.hand
<EMAIL_ADDRESS>chose an invalid action.")
return
this.playAction(action)
The current player plays an action from the hand, and performs the effect of the action.
playAction: (action) ->
<EMAIL_ADDRESS>plays #{action}.")
Subtract 1 from the action count and perform the action.
@current.hand.remove(action)
@current.inPlay.push(action)
@current.playLocation = 'inPlay'
@current.actions -= 1
this.resolveAction(action)
Another event that causes actions to be played, such as Throne Room,
should skip straight to resolveAction
.
resolveAction: (action) ->
@current.actionStack.push(action)
@current.actionsPlayed += 1
action.onPlay(this)
@current.actionStack.pop()
The “treasure phase” is a concept introduced in Prosperity. After playing
actions, you play any number of treasures in some order. This loop
repeats until the AI chooses null
, either because there are no treasures
left to play or because it does not want to play any more treasures.
doTreasurePhase: () ->
loop
validTreasures = [null]
Determine the set of unique treasures that may be played.
for card in @current.hand
if card.isTreasure and card not in validTreasures
validTreasures.push(card)
Ask the AI for its choice.
treasure = @current.ai.chooseTreasure(this, validTreasures)
break if treasure is null
<EMAIL_ADDRESS>plays #{treasure}.")
Remove the treasure from the hand and put it in the play area.
if treasure not in @current.hand
<EMAIL_ADDRESS>chose an invalid treasure")
break
this.playTreasure(treasure)
while (ctd = this.getCoinTokenDecision()) > 0
@current.coins += ctd
@current.coinTokens -= ctd
getCoinTokenDecision: () ->
ct = @current.ai.spendCoinTokens(this, @current)
if (ct > @current.coinTokens)
<EMAIL_ADDRESS>wants to spend more Coin Tokens as it possesses (#{ct}/#{@current.coinTokens})")
ct = @current.coinTokens
else
if (ct > 0)
<EMAIL_ADDRESS>spends #{ct} Coin Token#{if ct > 1 then "s" else ""}")
@current.coinTokensSpendThisTurn = ct
return ct
playTreasure: (treasure) ->
@current.hand.remove(treasure)
@current.inPlay.push(treasure)
@current.playLocation = 'inPlay'
treasure.onPlay(this)
getSingleBuyDecision
determines what single card (or none) the AI
wants to buy in the current state.
getSingleBuyDecision: () ->
buyable = [null]
checkSuicide = (this.depth == 0 and this.gainsToEndGame() <= 2)
for cardname, count of @supply
Because the supply must reference cards by their names, we use
c[cardname]
to get the actual object for the card.
card = c[cardname]
Determine whether each card can be bought in the current state.
if card.mayBeBought(this) and count > 0
[coinCost, potionCost] = card.getCost(this)
if coinCost <= @current.coins and potionCost <= @current.potions
buyable.push(card)
Don’t allow cards that will lose us the game
Note that this just cares for the buyPhase, gains by other means (Workshop) are not covered
if checkSuicide
buyable = (card for card in buyable when (not this.buyCausesToLose(@current, this, card)))
Ask the AI for its choice.
this.log("Coins<EMAIL_ADDRESS>Potions<EMAIL_ADDRESS>Buys<EMAIL_ADDRESS>this.log("Coin Tokens left<EMAIL_ADDRESS>choice = @current.ai.chooseGain(this, buyable)
return choice
doBuyPhase
steps through the buy phase, asking the AI to choose
a card to buy until it has no buys left or chooses to buy nothing.
Setting hypothetical
to true will skip gaining the cards and simply
return the card list.
doBuyPhase: () ->
while @current.buys > 0
choice = this.getSingleBuyDecision()
return if choice is null
<EMAIL_ADDRESS>buys #{choice}.")
Update money and buys.
[coinCost, potionCost] = choice.getCost(this)
@current.coins -= coinCost
@current.potions -= potionCost
@current.buys -= 1
Gain the card and deal with the effects.
this.gainCard(@current, choice, 'discard', true)
choice.onBuy(this)
Handle cards such as Talisman that respond to cards being bought.
for i in<EMAIL_ADDRESS>cardInPlay = @current.inPlay[i]
If a Mandarin put cards back on the deck, this card may not be there anymore. This showed up in a fascinating interaction among Talisman, Quarry, Border Village, and Mandarin.
if cardInPlay?
cardInPlay.buyInPlayEffect(this, choice)
Handle all the things that happen at the end of the turn.
doCleanupPhase: () ->
Clean up Walled Villages first
actionCardsInPlay = 0
for card in @current.inPlay
if card.isAction
actionCardsInPlay += 1
if actionCardsInPlay <= 2
while c['Walled Village'] in @current.inPlay
transferCardToTop(c['Walled Village'], @current.inPlay, @current.draw)
<EMAIL_ADDRESS>returns a Walled Village to the top of the deck.")
@extraturn = not @extraturn and (c['Outpost'] in @current.inPlay)
Discard old duration cards.
@current.discard = @current.discard.concat @current.duration
@current.duration = []
If there are cards set aside at this point, it probably means something went wrong in performing an action. But clean them up anyway.
if @current.setAside.length > 0
this.warn(["Cards were set aside at the end of turn", @current.setAside])
@current.discard = @current.discard.concat @current.setAside
@current.setAside = []
Check which multiplier cards ended up in multipliedDurations
, which means
they should be cleaned up as if they were duration cards. Remove them once
they’re dealt with. Disregard the other cards there for now.
for i in<EMAIL_ADDRESS>card = @current.multipliedDurations[i]
if card.isMultiplier
<EMAIL_ADDRESS>puts a #{card} in the duration area.")
@current.inPlay.remove(card)
@current.duration.push(card)
@current.multipliedDurations.splice(i, 1)
Handle effects of cleaning up the card, which may involve moving it somewhere else. We do this before removing cards from play because cards such as Scheme and Herbalist need to consider cards in play.
cardsToCleanup = @current.inPlay.concat().reverse()
for i in [cardsToCleanup.length-1...-1]
card = cardsToCleanup[i]
card.onCleanup(this)
Clean up cards in play.
while @current.inPlay.length > 0
card = @current.inPlay[0]
@current.inPlay = @current.inPlay[1...]
Put duration cards by default in the duration area, and other cards in play in the discard pile.
if card.isDuration
@current.duration.push(card)
else
@current.discard.push(card)
Discard the remaining cards in hand.
@current.discard =<EMAIL_ADDRESS>@current.hand = []
Reset things for the next turn.
@current.actions = 1
@current.buys = 1
@current.coins = 0
@current.potions = 0
@current.actionsPlayed = 0
@copperValue = 1
@costModifiers = []
Announce extra turn
if @extraturn
<EMAIL_ADDRESS>takes an extra turn from Outpost.")
Finally, draw the next hand of three/five cards.
if not (c.Outpost in @current.duration)
@current.drawCards(5)
else
@current.drawCards(3)
Make sure we didn’t drop cards on the floor.
if this.countTotalCards() != @totalCards
throw new Error("The game started with #{@totalCards} cards; now there are #{this.countTotalCards()}")
The player list is implemented so that the current player is always first in the list; the list rotates after every turn.
For convenience, the attribute @current
always points to the current
player.
rotatePlayer: () ->
@players =<EMAIL_ADDRESS>[@players[0]]
@current = @players[0]
@phase = 'start'
gainCard
performs the effects of a player gaining a card.
This is one of many events that affects a particular player, and
also has some effect on the overall state (in that the supply is
decreased). In this function and others like it, the player
argument
is the appropriate PlayerState object to affect. This must, of course,
be one of the objects in the @players
array.
gainCard: (player, card, gainLocation='discard', suppressMessage=false) ->
if this.depth == 0
delete @cache.gainsToEndGame
if @supply[card] > 0 or @specialSupply[card] > 0
for i in [player.hand.length-1...-1]
reactCard = player.hand[i]
if reactCard? and reactCard.isReaction and reactCard.reactReplacingGain?
card = reactCard.reactReplacingGain(this, player, card)
Keep track of the card gained, for Smugglers.
if player is @current
player.gainedThisTurn.push(card)
suppressMessage
is true when this happens as the direct result of a
buy. Nobody wants to read “X buys Y. X gains Y.” all the time.
if not suppressMessage
this.log("#{player.ai} gains #{card}.")
Determine what list the card is being gained in, and add it to the front of that list.
location = player[gainLocation]
location.unshift(card)
Remove the card from the supply
if @supply[card] > 0
@supply[card] -= 1
gainSource = 'supply'
else
@specialSupply[card] -= 1
gainSource = 'specialSupply'
Delegate to handleGainCard
to deal with reactions.
this.handleGainCard(player, card, gainLocation, gainSource)
else
this.log("There is no #{card} to gain.")
handleGainCard
deals with the reactions that result from gaining a card.
A card effect such as Thief needs to call this explicitly after gaining a
card from someplace that is not the supply or the prize list.
handleGainCard: (player, card, gainLocation='discard', gainSource='supply') ->
Remember where the card was gained, so that reactions can find it.
player.gainLocation = gainLocation
for own supplyCard, quantity of @supply
c[supplyCard].globalGainEffect(this, player, card, gainSource)
for own supplyCard, quantity of @specialSupply
c[supplyCard].globalGainEffect(this, player, card, gainSource)
Handle cards such as Royal Seal that respond to gains while they are in play.
for i in [player.inPlay.length-1...-1]
cardInPlay = player.inPlay[i]
cardInPlay.gainInPlayEffect(this, card)
Handle cards such as Watchtower that react to gains as a Reaction card.
for i in [player.hand.length-1...-1]
reactCard = player.hand[i]
if reactCard.isReaction
reactCard.reactToGain(this, player, card)
for opp in this.players[1...]
for i in [opp.hand.length-1...-1]
reactCard = opp.hand[i]
if reactCard.isReaction
reactCard.reactToOpponentGain(this, opp, player, card)
Handle the card’s own effects of being gained.
card.onGain(this, player)
Effects of an action could cause players to reveal their hand. So far, nothing happens as a result, but in the future, AIs might be able to take advantage of the information.
revealHand: (player) ->
this.log("#{player.ai} reveals the hand (#{player.hand}).")
drawCards
causes the player to draw num
cards.
This currently passes through directly to the PlayerState, without passing any information from the global state. An improved version would pass the state in case the player shuffles, and has Stash in the deck, and wants to use information from the state to decide where to put the Stash.
The drawn cards will be returned.
drawCards: (player, num) ->
player.drawCards(num)
discardFromDeck
puts num cards from the top of the deck directly
in the discard pile. It returns the set of cards, for the benefit of
actions that do something based on which cards were discarded.
discardFromDeck: (player, nCards) ->
drawn = player.getCardsFromDeck(nCards)
player.discard = player.discard.concat(drawn)
this.log("#{player.ai} draws and discards #{drawn.length} cards (#{drawn}).")
this.handleDiscards(player, drawn)
return drawn
doDiscard
causes the player to discard a particular card.
doDiscard: (player, card) ->
if card not in player.hand
this.warn("#{player.ai} has no #{card} to discard")
return
this.log("#{player.ai} discards #{card}.")
player.hand.remove(card)
player.discard.push(card)
this.handleDiscards(player, [card])
handleDiscards
looks through a list of cards and triggers their discard
reactions.
handleDiscards: (player, cards) ->
for card in cards
if card.isReaction
card.reactToDiscard(this, player)
doTrash
causes the player to trash a particular card.
doTrash: (player, card) ->
if card not in player.hand
this.warn("#{player.ai} has no #{card} to trash")
return
this.log("#{player.ai} trashes #{card}.")
player.hand.remove(card)
card.onTrash(this, player)
@trash.push(card)
doPutOnDeck
puts a particular card from the player’s hand on top of
the player’s draw pile.
doPutOnDeck: (player, card) ->
if card not in player.hand
this.warn("#{player.ai} has no #{card} to put on deck.")
return
this.log("#{player.ai} puts #{card} on deck.")
player.hand.remove(card)
player.draw.unshift(card)
getCardsFromDeck
is superficially similar to drawCards
, but it does
not put the cards into the hand. Any code that calls it needs to determine
what happens to those cards (otherwise they’ll be dropped on the floor!)
This is useful for effects that say “draw n cards, do something based on them, and discard them”.
getCardsFromDeck: (player, num) ->
player.getCardsFromDeck(num)
allowDiscard
allows a player to discard 0 through num
cards.
added typeFunc to only allow discards of certain type of cards.
allowDiscard: (player, num, typeFunc = (card) -> true) ->
discarded = []
while discarded.length < num
In allowDiscard
, valid discards are the entire hand, plus null
to stop discarding.
validDiscards = ( card for card in player.hand when typeFunc(card?) ).slice(0)
validDiscards.push(null)
choice = player.ai.chooseDiscard(this, validDiscards)
return discarded if choice is null
discarded.push(choice)
this.doDiscard(player, choice)
return discarded
requireDiscard
requires the player to discard exactly num
cards,
except that it stops if the player has 0 cards in hand.
requireDiscard: (player, num, typeFunc = (card) -> true) ->
discarded = []
while discarded.length < num
validDiscards = ( card for card in player.hand when typeFunc(card) ).slice(0)
return discarded if validDiscards.length == 0
choice = player.ai.chooseDiscard(this, validDiscards)
discarded.push(choice)
this.doDiscard(player, choice)
return discarded
allowTrash
and requireTrash
are similar to allowDiscard
and
requireDiscard
.
allowTrash: (player, num) ->
trashed = []
while trashed.length < num
valid = player.hand.slice(0)
valid.push(null)
choice = player.ai.chooseTrash(this, valid)
return trashed if choice is null
trashed.push(choice)
this.doTrash(player, choice)
return trashed
requireTrash: (player, num) ->
trashed = []
while trashed.length < num
valid = player.hand.slice(0)
return trashed if valid.length == 0
choice = player.ai.chooseTrash(this, valid)
trashed.push(choice)
this.doTrash(player, choice)
return trashed
gainOneOf
gives the player a choice of cards to gain. Include
null
if gaining nothing is an option.
gainOneOf: (player, options, location='discard') ->
choice = player.ai.chooseGain(this, options)
return null if choice is null
this.gainCard(player, choice, location)
return choice
attackOpponents
takes in a function of one argument, and applies
it to all players except the one whose turn it is.
The function should take in the PlayerState of the player to attack,
and alter it somehow. This function can also involve the global state:
it doesn’t need to be passed in because it’s already in scope in the place
where the action is defined. See Militia
in cards.coffee
for an
example.
attackOpponents: (effect) ->
for opp in @players[1...]
this.attackPlayer(opp, effect)
attackPlayer
does the work of attacking a particular player, including
handling their reactions to attacks.
attackPlayer: (player, effect) ->
attackEvent gets passed to each reactToAttack method. Any card may block the attack by setting attackEvent.blocked to true
attackEvent = {}
Reaction cards in the hand can react to the attack
reactionCards = (card for card in player.hand when card.isReaction)
for card in reactionCards
card.reactToAttack(this, player, attackEvent)
for card in player.duration
card.durationReactToAttack(this, player, attackEvent)
Apply the attack’s effect unless it’s been blocked by a card such as Moat or Lighthouse
effect(player) unless attackEvent.blocked
copy()
makes a copy of this state that can be safely mutated
without affecting the original state.
Ideally, the AI would be passed a copy of the state, with unknown information randomized, when it is asked to make a decision. This would allow it to try simulating the effects of various plays without actually breaking the game. But this isn’t implemented yet, so make this a TODO.
copy: () ->
newSupply = {}
for key, value of @supply
newSupply[key] = value
newSpecialSupply = {}
for key, value of @specialSupply
newSpecialSupply[key] = value
newState = new State()
If something overrode the log function, make sure that’s preserved.
newState.logFunc = @logFunc
newPlayers = []
for player in @players
playerCopy = player.copy()
playerCopy.logFunc = (obj) ->
newPlayers.push(playerCopy)
Copy card-specific state
newCardState = {}
for card, state of @cardState
If the card state has a copy method, call it, otherwise just shallow copy the state
if state.copy?
Objects with a copy method
newCardState[card] = state.copy?()
else if typeof state == 'object'
Objects with no copy method
newCardState[card] = copy = {}
copy[k] = v for k, v of state
else
Simple types
newCardState[card] = state
newState.players = newPlayers
newState.supply = newSupply
newState.specialSupply = newSpecialSupply
newState.cardState = newCardState
newState.trash = @trash.slice(0)
newState.current = newPlayers[0]
newState.nPlayers = @nPlayers
newState.costModifiers = @costModifiers.concat()
newState.copperValue = @copperValue
newState.phase = @phase
newState.cache = {}
newState
hypothetical(ai)
returns a State and PlayerState that an AI can do
whatever it wants to without affecting the real state:
An AI that wants to test a hypothesis should do this: [state, my] = state.hypothetical(this)
hypothetical: (ai) ->
state = this.copy()
Rotate through players until this AI is the current player.
counter = 0
while state.players[0].ai isnt ai
counter++
if counter > state.nPlayers
throw new Error("Can't find this AI in the player list")
state.players = state.players[1...].concat([state.players[0]])
state.depth = this.depth + 1
my = null
for player in state.players
if player.ai isnt ai
player.ai = ai.copy()
We don’t know what’s in their hand or their deck, so shuffle them together randomly, preserving the number of cards.
handSize = player.hand.length
combined = player.hand.concat(player.draw)
shuffle(combined)
player.hand = combined[...handSize]
player.draw = combined[handSize...]
else
shuffle(player.draw)
my = player
[state, my]
Functions for comparing, used for sorting
Rob says: this is pretty AI-specific. It’s also an unnecessarily complex operation, even given caching. The choices are already in order in the actionPriority; they need to be filtered, not sorted.
compareByActionPriority: (state, my, x, y) ->
my.ai.cacheActionPriority(state,my)
my.ai.choiceToValue('cachedAction', state, x) - my.ai.choiceToValue('cachedAction', state, y)
compareByCoinCost: (state, my, x, y) ->
x.getCost(state)[0] - y.getCost(state)[0]
Games can provide output using the log
function.
log: (obj) ->
Only log things that actually happen.
if @depth == 0
if this.logFunc?
this.logFunc(obj)
else
if console?
console.log(obj)
A warning has a similar effect to a log message, but indicates that something has gone wrong with the gameplay.
warn: (obj) ->
if console?
console.warn("WARNING: ", obj)
Define some possible tableaux to play the game with. None of these are actually legal tableaux, but that gives strategies more room to play.
this.tableaux = {
moneyOnly: []
moneyOnlyColony: ['Platinum', 'Colony']
all: c.allCards
}
How to remove something from a JavaScript array. Modifies the list and returns the 0 or 1 removed elements.
Array.prototype.remove = (elt) ->
idx = this.lastIndexOf(elt)
if idx != -1
this.splice(idx, 1)
else
[]
Define the additional tableau of everything but Platinum/Colony. If there’s a better way to remove items from a JS array, I’d like to know what it is.
noColony = this.tableaux.all.slice(0)
noColony.remove('Platinum')
noColony.remove('Colony')
this.tableaux.noColony = noColony
This customized clone function will not make unnecessary copies of cards and AIs. However, it doesn’t seem to work.
cloneDominionObject = (obj) ->
if not obj? or typeof obj isnt 'object'
return obj
if (obj.gainPriority?) or (obj.costInCoins?)
return obj
newInstance = new obj.constructor()
for own key, value of obj
newInstance[key] = cloneDominionObject(value)
newInstance
General function to randomly shuffle a list.
shuffle = (v) ->
i = v.length
while i
j = parseInt(Math.random() * i)
i -= 1
temp = v[i]
v[i] = v[j]
v[j] = temp
v
Count the number of times a value appears in a list, coercing everything to its string value.
countStr = (list, elt) ->
count = 0
for member in list
if member.toString() == elt.toString()
count++
count
Sort by numeric value. You’d think this would be in the standard library.
numericSort = (array) ->
array.sort( (a, b) -> (a-b) )
When modifying built-in methods of core types, we need to play nice with other libraries. For instance, our Array#toString method modifies the behavior in a way that breaks the CoffeeScript compiler.
Modifies built-in methods of core Javascript types in a way that’s reversible
modifyCoreTypes = ->
Make Array#toString output more readable
Array::_originalToString ||= Array::toString
Array::toString = ->
'[' + this.join(', ') + ']'
Reverses modifications to core Javascript types
restoreCoreTypes = ->
Array::toString = Array::_originalToString if Array::_originalToString?
delete Array::_originalToString
useCoreTypeMods takes an object and the name of a method. It then wraps that method so that it correctly uses and restores our core type modifications. The modifications are visible within the method body and any child method calls, but they are cleaned up when leaving the method
useCoreTypeMods = (object, method) ->
originalMethod = "_original_#{method}"
unless object[originalMethod]?
object[originalMethod] = object[method]
object[method] = ->
try
modifyCoreTypes()
this[originalMethod](arguments...)
finally
restoreCoreTypes()
Use our core type modifications within the State object. These three methods are the ones called by external functions to set up and play a game.
useCoreTypeMods(State::, 'setUpWithOptions')
useCoreTypeMods(State::, 'gameIsOver')
useCoreTypeMods(State::, 'doPlay')
Export the State and PlayerState classes for other modules to use.
this.State = State
this.PlayerState = PlayerState
Recall that this code begins with:
{c} = require './cards' if exports?
This means “get the variable named c
from the module ./cards
. Unless
there’s no module system. In that case, don’t.”
Here’s why that is useful. When the code
is running inside node.js, it will use node.js’s import system. This
uses the predefined function require
, which doesn’t exist in a
Web browser’s JS environment.
When running in a web browser, there is no sane way for one module to import another. Instead, the typical practice — which we will use too — is to just load a bunch of JavaScript files into the same global namespace.
In that case, the variable c
already exists without any additional effort
from us. We’re polluting the global namespace and defeating some of the
point of modules, but that’s how most JavaScript in the wild works anyway.


# devops and continuous delivery a discussion with Tradify
# hello. I'm Luke
DORA and Accelerate metrics
deployment frequency
lead time
change failure percentage
time to restore
Continuous delivery enables evolutionary architecture
Continuous delivery reduces waste
Continuous delivery does not compromise stability
thank you.


{% extends 'sitewide/base.html' %} {% block title %}People{% endblock %} {% load markdownify %} {% load react %} {% block body %}
See activities and analysis related to politicians and private influencers from across Missouri and beyond.
Search for People


Running Infrastructure- and Researchprojects
FPGA-Design with VHDL and Simulink
Short summary
With this application the FHTW applies a further education course for engineers, technicians and scientists to provide them a trainig in modern, simulate-based methods of development for circuits with FPGSs (Field Programmable Gate Array).
A FPGA is a configurable digital integrated circuit (IC) which functionality is based on a kind of programming. Due to a specific configuration of intern structures it is possible to implement simple flip-flops or counters up to high complex circuits like signal processors combined in a circuit. By now FPGAs are used in all areas of digital technology. They offer special advantages in case of multiple reconfigurations of components without changing their hardware structure. This point is important in development of prototypes or small series-production. So FPGAs are a cheap alternative to manufacturers of semiconductor technology.
The special feature here is the use of new software methods, which allows the generation of prototypes directly from the system simulation environment with an FPGA. This is for companies, which use digital electronics in their products, to reduce development time to market decisively. It is understood that thus the circle of dedicated workers who are affected by unemployment or threatened, an entry in an interesting and forward-looking field of work is given and an upgrading of relevant employees already achieved.
How and by what methods should this goal be achieved?
The resulting course covers all steps from the system simulation until building a prototype. The measure is divided into two parts. In the first part customized multimedia work materials will be created to build a sustainable course programme. The laborative part should take a large part in training units, it should be able to consider the concerns of companies targeted has taken place. To this end, a library of various functions with this FPGA tool should be created, which also is available for course participants. In the second part this course will be performed and integrated in the range of FHTW-training opportunities.
With the help of a scientific employee the applicants
- develop electronic documentaion for this couse
- create teaching examples
- create a module library
What should like to be achieved?
Chances originate from the application of this new methodology for new workplaces, in particular by with it linked expansion of product spectra which can be equipped with the help of this design methodology with better electronics, however, also the possibilities of existence foundations and services offer in the area of the digital electronics design.
The establishment of a course at the FHTW appears as an ideal base for training in this methodology. On the one hand practise-experienced instructors exist who apply this technology already for many years in her projects, and on the other hand has the FHTW a high competence degree for the realisation of continuing education offers.
Berlin FHTW maintains narrow contacts to the industry and to service providers as well as to users of the electronics technology. Thus cooperations with companies exist by which practically oriented and to the market oriented education is promoted. Cooperations with companies to concrete projects are planned. In the end, the companies which deliver the necessary software will also support this plan. (see LOI).
Computers Aided design (CAD) and computer Aided Manufacturing (CAM) stamp the work of the engineer.The contact with these programs can be learnt only about the practical work. Hence, the programs Matlab and Simulink are introduced here and introduced in the work with Simulink. This is built up gradually so that at first the elementary simulation functions are learnt afterwards the inclusion of the periphery and after that the special contact with the FPGAs on which the ready simulation model is loaded.
This assumes teaching material qualitatively of high standing which must be made specially for these courses, then can be used, however, also with lasting effect.
On account of the importance of the used materials for an efficient education a subdivision of the whole project is planned in two phases. The first phase is planned for the design of the practical exercises of the course and the production of all backing-up materials. In the second phase the course is offered to participants. Both phases go over into each other, in a pilot's phase with diminished contents the first experiences are already won for the other elaboration and the second course program.


We are couting cluster-capacity for you and generating new report in every {{.Period}} seconds. We always remember last {{.CacheSize}} records. You can see the results or update the scheduled pod using api-reference specified in /doc sirectory or on the project page: https://github.com/kubernetes-incubator/cluster-capacity /p>


As part of my journey to become a better UX and UI Designer, learning a new tool becomes a necessary learning curve that one has to endure. Already being proficient in using Adobe's XD and Zeppelin, having some commercial experience using XD both tool's, another tool that other designer's were persuading me to learn was called Figma. Figma on one hand, is similar to the aforementioned tools in the sense that - yes, you can design Wireframes, High Fidelity designs, design Vectors make and share prototypes alike. However, Figma offers a feature that unlocks the boundaries that all of the other tools have and that is responsive design using Auto-Layer! Auto Layer, if you have some development experience is basically Flex for your designs. Adding and removing constraints through Fluid containers for any screen size, all in all making designing more efficient and precise.
Please read on through this Case Study on recreating Google Chromes homepage using Figma - Thank You and please enjoy!
The vision for this case study was to establish a clear understanding on using Figma as a design tool to expand my knowledge in UI and UX Design. Focusing on:
The issue that designers have whilst using some Design software, is although their end designs are
very well engineered
and User tested, the software itself - in regards to Fluid Design was found to be either non
existent or sub standard.
I intended to research a previously unexplored Design Software called Figma, having being influenced
by other designers
and intrigued from research conducted.
The aim was to eliminate 'break point designs' and have one single responsive and interactive design
that developers could
efficiently utilise on handover. It was discovered that although Figma did provide a tool called,
'Auto-Layer,' which
encapsulated containers into a more flexible container for a more fluid control over responsiveness,
it didn't cater
completely and therefore a single page design was not possible at the time of writing (2021).
Tasked with researching and developing new skills in using a new Design Software, naming Figma, to create a single paged interactive Fluid Design rather than having the usual - three non-responsive break point design. Research discovered that Figma does have a feature that can cater for such a task as an integral part of its Software, called, "Auto Layer." As the name suggests it automatically adds a layer to the selected items, which when used correctly, encapsulates them into a fluid child-container. Which, by itself add's constraints and enforced it to behave responsively either in a column or row on user interaction. This does add a further dimension to designing, when this is also added to the parent container, it plays its part and makes the whole design responsive.
It does have a major issue though. At the time of writing (2021), it was discovered that it's not completely the answer. As you will you see from this case study, the "Auto Layer," feature will only work up to a certain point, whereby the content inside is no longer responding effectively and a new breakpoint is required. Concluding that although having just one single interactive and responsive design was not possible yet. That being said it will make for more efficient designing and development having only needing two breakpoint designs which are also responsive and interactive.
Hands on UX Researcher, Designer and Test Facilitator.
Hands on UX Researcher, Designer, Tester Facilitator for the Design.
Desk Research, prototyping and Hi-Def Design.
Two day's discovery and ideation, followed by two day's of rapid prototyping, one day final Product Design.
I began by researching the existing market on Design Software that included fluid design when the user interacted. After some investigation and analysis of 5 of the most popular Design Software available on the market to date (2021), surprisingly only one product catered for fluid interactive design. What was more surprising was that this type of feature more than likely in the a marketing sense, would be a "paid for," feature, certainly Adobe although they do have a time limited version of their Design Software available on the market, wouldn't shy away from charging for this type of feature for their product. Figma's free version comes with this for all available versions.
What followed were efforts to discover which software offered more design tools, which had the best user reviews and more importantly which software offered support to eliminate the break point design system that would enable to have one responsive and interactive design as the end goal, or at least which would have the less if break points were needed:
Carrying out Desk Research on the contenders with relatable Software on the market today for Design, moreover, which offered the best experience over all and which had the aforementioned Fluid Design feature. Below are the discovered 4 main contenders following the Desk Research and which products had the greater Statistical Deviation following the customer reviews in terms of User Experience :
Adobe XD whilst certainly the most successful for Longevity by consistently adapting and updating, an
equal amount of good and bad reviews
were discovered through out.
The Pros: Simplistic UI, Low Learning
Curve, Sharing And Cross Platform Capabilities, 'Repeat Grid' Makes Designing In This
Respect Most Efficient.
The Cons: No Security To Protect The Mock
Ups
When Sharing, No Tools For Animating Elements (Key Frames),
❌ No Fluid Design Feature.
Figma is a vector graphics editor and prototyping tool which is primarily web-based, with additional
offline features enabled by desktop applications for macOS and Windows.
The
Pros: Low Learning Curve, Simplistic UI, Cross Platform aAnd Collaboration, Auto Layout
Prototyping.
The Cons: Both Web And Software Are Memory Load Heavy,
No
Built In Animation Tools (Keyframes),
Converted CSS Code Is Below Standard.
✔ Fluid Design Feature Found!
InVision is a prototyping, collaboration and workflow tool.
The
Pros: Prototyping, Supports Gestures, Transitions And Animations For Web, Cross
Platform,
Version Control
The Cons: More Difficult UI Than Other Tools,
Sharing Settings And Toolbar Are Not Always Intuitive,
Element Inspector Is Not Always Precise;.
❌ No Fluid Design Feature.
Affinity Designer is a vector graphics editor developed by Serif for macOS, iPadOS, and
Microsoft
Windows.
The
Pros: Intuitive User Interface, Supports Gestures, Powerful Artistic Tools, Cross
Platform,
Excellent Photoshop/Illustrator Import & Export
The Cons:
Requires
Paid
Subscription To Export Design,
Poor Customer Support,
Unstable.
❌ No Fluid Design Feature.
Based on discovery research findings I came up with three hypothesis to ensure successful
product
adoption. These covered:
Data collected from the User Research and Discovery phase produced User expectations and Future Development Opportunities for further development of the application, which also gave more information on what to include for the website. This data along with expectations for the website design advanced Ideation into Hypothesis and Idea Prioritisation.
Concentrating on high impact feature sets allowed me to create a story that could be split into a few major user scenarios: Product Identity, simple HCI and familiarity inspired by the product itself and intrigue from the competitive research. Focusing on the natural user flow, the usability and accessibility of the website, whilst keeping the focus on branding and the business advertisement requirements, the following steps in designing the website followed.
Using UX tools to gain some insights on what the competition's SEO keywords were, how they ranked with other competitors, spot new opportunities, show the exact content needed and revealed design patterns that are collectively successful for the user, product and business.
Data recorded during User Interviews and the public Surveys enabled me to capture and encapsulate the users feelings towards the products tested and through the data recorded during the interviews, now in Persona's, I was able to produce a Naturel User Flow for the website.
During Rapid Prototyping, several iterations generated during a short period of time, the features were created and tested in an attempt to optimize characteristics like shape, size, and overall usability based on user feedback and analysis. Final tests produced the final prototype and the Natural User Flow had been established.
Once the final iteration of the wireframes were acknowledged after User testing, all features and functionality was transferred to Hi-Def Designs using Adobe XD and Illustrator for the icons. These were tested using Think Aloud Protocol, pain points were corrected and final designs were completed.
The prototype has been tested on 15 users (5 for each of the created persona's), in order to to validate my Hypothesis. Using the previously determined User Flow to guide the User through the prototype. User's paralinguistic features were recorded using a web-cam and video recording software at the agreement of the participant, they were tested ethically a new set of participants were brought in for the second wave of testing. The identity of the participants shall remain anonymised as agreed.
From the previously conducted survey, willing participants tested the prototype created for mobile and desktop viewport's using the Think Aloud Protocol. Asking a series of open ended questions the test administrator was able to understand how the user's felt about the product whilst also testing the age ranges specified earlier to expand the customer base.
All Feedback was analysed, errors were caught and designs improved greatly thanks to this. I observed almost entirely positive feedback from the final designs.
Based on the findings from both the UX research and the Design validation sessions I was able to produce
a list of changes that were addressed and updated in the prototype along with any potential future
alterations for the Application passed onto the company.
It was realised during the Validation stage that all of the user's became concerned when they clicked on
the video section of the design and wondered why the video didn't play. It was mentioned prior to
testing that there was no promotional video provided as the
company wanted their application to appeal to the general public and at that moment in time was
developed as businesses tool.
They did
not want to confuse the participants by advertising something that it wasn't going to be, so a decision
on their part was to not include the video. Another thing was because of the potential improvements
found was
significantly different to the application that they had, some of the details in the designs such as
descriptive text will
change once those improvements are developed.
Below you will find links to the Mobile, Desktop and the Design Specifications for the website. Please
enjoy and thank you.
Hopefully you liked what you seen, how the story unfolded and more importantly why the user experience was so important for potential development opportunities for the actual application and for the website design too.
You can click any of the links in the footer to contact myself through the social media platforms or by clicking clicking here and sending me a message. I usually call or message back within 8 hours.
Thank you for your time.


Go is an open source programming language that makes it easy to build simple, reliable, and efficient software
Go (or golang) is a simple, general purpose programming language that excels at writing things like backend services. It’s the language used to make Docker, among many other things.
I’m currently using Golang almost exclusively and I’m looking for remote freelance jobs. I’ve therefor compiled this list for my own sake, but I guess it can be useful to others as well.
This is probably the site with the most Go specific listings. Many jobs in Europe and the US. It seems like searching for "remote" is not entirely reliable, so double check the results before getting too excited about a job :). This site also has developer profiles, and you can get listed just by tweeting them.
Also a good place to find Go-specific job listings. This site also have developer profiles, but registering here is more work since they require more information. Seems like most of the jobs are full time at the moment. Remote jobs can sometimes be US-specific.
Great site with reposts jobs from other places. You can often click the "Apply for job" to get to the website with the original listing.
Similar to the above, but fewer listings.
Remote / telecommute jobs site.
There’s a couple of listings here, try searching for "golang" or maybe "go".
The Gophers Slack is quite active and has a separate "Jobs" channel.
Not super active, 2 postings in the four first months of 2016.
Hacker News has monthly "Ask HN: Who is hiring?" posts. This is an easy interface view and search this posts, you can filter on words etc. More geeky than most job listing sites =)
Startup jobs in the US and a few other places around the world. (No search function?)
Remote Jobs at Angel List: https://angel.co/job-collections/remote
Golang jobs at Angel List. Varies how much these emphasize Go. https://angel.co/golang/jobs
Remote jobs tagged with golang: http:// stackoverflow.com/jobs?searchTerm=[golang]&allowsremote=true
Remote jobs containing the word "golang": https://stackoverflow.com/jobs?searchTerm=golang&allowsremote=true
I was supriesd to find a few hits for "golang" and "remote" on Monster.com: http://jobs.monster.com/search/?q=golang&where=remote
No Go jobs when I checked.
No Go jobs when I checked.
No Go jobs when I checked.
Hard to know for sure, but I could not find any Go jobs when I checked.
Startups in the nordics. No Go jobs when I checked.
"Exclusive" site for freelancers. Don’t know if there’s demand for Go programmers here, they don’t list their openings. Last I checked (in 2014?) the onboarding process was very automated and not that great. You could not do it in Go, but maybe that has changed.
A collection of the best resources for remote workers.
(Original gopher graphics by Renee French, modifications by unknown.)


Tess Palan
About me: I'm a Data Analytics student that wants to work in the music industry
Email:
<EMAIL_ADDRESS>GitHub
Linkedin
Books
Shows
Music Artists
Harry Potter
Firefly Lane
The Chainsmokers
This is Not a Fashion Story
Scandal
Justin Beiber
Grey's Anatomy
Dillon Francis
My First HTML Bonus


A system error has occurred(500).
We apologise for the inconvience.
What to do from here...
Report to HVP system admin
Go to the Home page
If difficulties persist, please contact the System Administrator of this site and report the error


A JavaScript Data Display Framework
INFO: plastic.js is currently in alpha phase. Excpect issues!
What is it about?
plastic.js is a JavaScript framework that simplifies the common tasks of data retrieval, processing and representation.
It is not meant to replace existing visualization / data processing libraries but to integrate them into one bigger, coherent framework.
For the best way to getting started, take a look at the user documentation!
Also, there's an online presentation and a paper about plastic.js
Features
General
- Open Source at GitHub
- Modular architecture that is easy to extend
- Asynchronous architecture that loads and displays the data independent from the rest of your site
- Platform independend
Data Retrieval
- Quering data from remote APIs and databases! SPARQL and SemanticMediaWikis are supported.
- Load data from files in various formats
- Directly embed your data into the plastic tag
Data Processing
- Support for various data formats
- Provides a simple and an advanced default data format
Data Display
- Several Display modules that rely on already existing and mature libraries
- Lazy loads additional dependencies for you automatically
Gallery
Check out some of the (live) examples with documentation below:
Simple Table
Advanced Table
Bar Chart
Pie Chart
Line Chart


airImageCache
An extremely simple UIImage cache manager backed by both an in-memory NSCache and file system /Caches folder.
How to use airImageCache
Installation is best managed using Carthage. Add github "airg/iOS-airImageCache"
to your cartfile and run carthage install
, see Carthage Installation Guide.
Documentation
Check out the documentation. All calls should also be documented in the generated Swift interface.
How it’s made
airImageCache is currently written in Swift 4 with Xcode 9.2.
Documentation is generated using Jazzy, a very useful tool for generating pretty docs.
Contributing
Before opening a pull request, be sure to run jazzy
to regenerate the docs.


Native MTP interconnect on Mac/Linux
Connecting your phone to your computer via MTP isn’t as easy as it should be: the Android File Transfer app is very lackluster and I wanted to have native file manager integration so that my phone would show up in either Nautilus on Debian or Finder on Mac. Here’s how I got it working.
Linux setup
On Debian (or Debian derivatives like Ubuntu):
sudo apt-get install libfuse-dev android-tools-adb
Mac setup
Install Homebrew (http://brew.sh) and OSXFuse (https://osxfuse.github.io/) then run:
brew update
brew install android-platform-tools
Clone, build, and setup adbfs
We’ll be using adbfs
to mount our Android phone:
git clone git://github.com/spion/adbfs-rootless.git
cd adbfs-rootless
make
Create a mount point
mkdir ~/phone
Mount device as follows:
./adbfs ~/phone
And your phone should be mounted and visible the same way as any DAS device (e.g. External drives).
Troubleshooting
Try reseting and restarting adb
and the mount point
killall -9 adb; sudo umount -f ~/phone


{% extends "advanced_reports/backoffice/base.html" %} {% load i18n %} {% block content-override %}
{% blocktrans %}Successfully signed out.{% endblocktrans %}