C++ Bowling Kata Result 69

Posted by Brett Schuchert Tue, 27 Oct 2009 20:37:00 GMT

I’m teaching a TDD and Refactoring class this week using C++. Since I had not recently wrote the bowling kata in C++, I figured it was about time to do it again.

Unlike the previous Scala version, this one only addresses the happy-path. I do not consider throwing too many balls or scoring too many pins in any frame. However, having just written this in Scala, I’m sure I could do something similar in C++.

I just switched to CppUTest 2.0 and something I noticed is that if you use <vector> or other std-based classes, you need to make sure to include those first before including <CppUTest/TestHarness.h>. This is because CppUTest overloads new and delete, which causes havoc with the std-based classes. No big deal, I just made sure to include that file as the last header (rather than the first, which is what I used to do).

Here are the various files:

RunAllTests.cpp

1
2
3
4
5
#include <CppUTest/CommandLineTestRunner.h>

int main(int argc, char** argv) {
  CommandLineTestRunner::RunAllTests(argc, argv);
}

BowlingScoreCardTest.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
#include "BowlingScoreCard.h"

#include <CppUTest/TestHarness.h>

TEST_GROUP(BowlingScoreCard) {
  BowlingScoreCard* card;

  TEST_SETUP() {
    card = new BowlingScoreCard;
  }

  TEST_TEARDOWN() {
    delete card;
  }

  void throwOne(int value) {
      card->recordThrow(value);
  }

  void throwMany(int rolls, int value) {
    for(int i = 0; i < rolls; ++i)
      throwOne(value);
  }

  void confirmScoreIs(int expected) {
    LONGS_EQUAL(expected, card->score());
  }
};

TEST(BowlingScoreCard, noRollsGame) {
  confirmScoreIs(0);
}

TEST(BowlingScoreCard, throwAll0s) {
  throwMany(20, 0);
  confirmScoreIs(0);
}

TEST(BowlingScoreCard, throwAll1s) {
  throwMany(20, 1);
  confirmScoreIs(20);
}

TEST(BowlingScoreCard, throwOneSpare) {
  throwOne(7);
  throwOne(3);
  throwOne(6);
  throwMany(17, 0);
  confirmScoreIs(22);
}

TEST(BowlingScoreCard, all5sthrown) {
  throwMany(21, 5);
  confirmScoreIs(150);
}

TEST(BowlingScoreCard, throwOneStrike) {
  throwOne(10);
  throwOne(4);
  throwOne(3);
  confirmScoreIs(24);
}

TEST(BowlingScoreCard, perfectGame) {
  throwMany(12, 10);
  confirmScoreIs(300);
}

TEST(BowlingScoreCard, dutch200StrikeSpare) {
  for(int i = 0; i < 10; ++i) {
    throwOne(10);
    throwMany(2, 5);
  }
  throwOne(10);
  confirmScoreIs(200);
}

TEST(BowlingScoreCard, dutch200SpareStrike) {
  for(int i = 0; i < 10; ++i) {
    throwMany(2, 5);
    throwOne(10);
  }
  throwMany(2, 5);
  confirmScoreIs(200);
}

BowlingScoreCard.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#pragma once

#ifndef BOWLING_SCORE_CARD_H
#define BOWLING_SCORE_CARD_H

#include <vector>
using namespace std;

class BowlingScoreCard
{
public:
  enum { Frames = 10, Mark = 10 };

  BowlingScoreCard();
  virtual ~BowlingScoreCard();
  int score();
  void recordThrow(int roll);

private:
  typedef vector<int> v_int;
  typedef v_int::size_type size_type;

  int scoreFrameAt(size_type index);
  int nextTwoRollsSummed(size_type index);
  int scoreAt(size_type index);
  int frameSizeAt(size_type index);
  bool isStrikeAt(size_type index);
  bool isSpareAt(size_type index);
  int scoreStrikeAt(size_type index);
  int scoreSpareAt(size_type index);

  v_int rolls;
};

#endif

BowlingScoreCard.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#include "BowlingScoreCard.h"

BowlingScoreCard::BowlingScoreCard() {
}

BowlingScoreCard::~BowlingScoreCard() {
}

int BowlingScoreCard::score() {
  int score = 0;

  for(int index = 0, frame = 0; frame < Frames; ++frame) {
    score += scoreFrameAt(index);
    index += frameSizeAt(index);
  }

  return score;
}

int BowlingScoreCard::scoreFrameAt(size_type index) {
  if(isStrikeAt(index))
    return scoreStrikeAt(index);
  else if(isSpareAt(index))
    return scoreSpareAt(index);

  return nextTwoRollsSummed(index);
}

bool BowlingScoreCard::isStrikeAt(size_type index) {
  return scoreAt(index) == Mark;
}

bool BowlingScoreCard::isSpareAt(size_type index) {
  return !isStrikeAt(index) && nextTwoRollsSummed(index) == Mark;
}

int BowlingScoreCard::scoreStrikeAt(size_type index) {
  return Mark + nextTwoRollsSummed(index + 1);
}

int BowlingScoreCard::scoreSpareAt(size_type index) {
  return Mark + scoreAt(index + 2);
}

int BowlingScoreCard::frameSizeAt(size_type index) {
  if(scoreAt(index) == Mark)
    return 1;
  return 2;
}

int BowlingScoreCard::nextTwoRollsSummed(size_type index) {
  return scoreAt(index) + scoreAt(index + 1);
}

int BowlingScoreCard::scoreAt(size_type index) {
  return index < rolls.size() ? rolls[index] : 0;
}

void BowlingScoreCard::recordThrow(int roll) {
  rolls.push_back(roll);
}

I sure do miss refactoring tools!-)

Comments

Leave a response

  1. Avatar
    Stan about 3 hours later:

    “I sure do miss refactoring tools!-)” It shows in your code :) Is this C++ or for a specific implementation of C++ as “pragma once” when not recognised by the compiler is allowed to do anything it wants.

    I have not used this framework yet many other C++ frameworks and they all return a result of the tests do you not want this information returned from main?

    Files do not end with an extra line, yet I am assuming this is an error when posting to the blog.

    BowlingScoreCard.h pollutes the global namespace via the horrible “using namespace std”!

    There is no need for BowlingScoreCard constructor as it does nothing the default does not, also why the virtual destructor are you expecting to derive from the class as you will pay for a vtable(on most implementations).

    The function scoreAt looks really wrong to me. If you are indexing out of range that is an error and should not return zero, maybe use vector’s at which throws on out of bounds.

    Should the score function be using the enum constant frame as it is quite possible you can throw more times than Frame and this is not accounted for, therefore would it not be better to do some checking in throw and use iterators or at least the vectors size to calculate the score. I know you mention this but still it is wrong.

    Also why it the constant an enum and not a const int. With forward thinking in mind and IIRC enums will not be promoted so easily to in C++0x.

    You have loops in your tests should they be there?

  2. Avatar
    Brett L. Schuchert 2 days later:

    Stan,

    The #pragma once should be safely ignored by ANSI compliant compilers that do not understand it. In general, #pragmas that are not understood should be ignored. What compiler is giving you problems? Notice that I also put in the standard conditional include guards, just in case I have an older compiler. This is boilerplate C++ code, so I don’t get your point.

    When I run the tests they either pass or fail. If they pass, I don’t need more information. If they fail, then I first need to know which tests failed. I would know that from execution and I would start there. So what are you looking for?

    Files not ending with a blank line? Was that really necessary? I can copy the code into an editor as is (vi is my editor of choice), save it and go. Are you picking nits or is there something else you’re trying to get at?

    The global pollution of the namespace is a good point. For this little practice session I didn’t care. In fact, where I used it, I was silly to do so anyway as I used nested typedefs.

    I do not agree with your comment about the ctor. Auto-generated ctors lead to larger .o files and code on many compilers. As for the virtual dtor, I add that. I don’t work in embedded systems, so the addition of the vtable is not much of an issue. If I were working in an embedded system, I’d be a lot more picky about the use of virtual methods anywhere. But I’d still explicitly code both of them rather than let the compiler regenerate the code everywhere instances are constructed.

    I do not agree with your comment about scoreAt. Given my current system definition (its tests), the scoreAt works fine. I can score a bowling game by hand with an empty card. The array is empty. Asking for the score at a location that does not yet exist is a score of 0. Putting validation of the sort your suggesting at such a low level seems backwards. I would prefer to validate input right as I get it. That method is a private method used for internal purposes only, so its definition is perfectly fine as it is. Its implementation falls under the category of the “null-object pattern”.

    Loops in tests seem fine to me. I’m trying to fill out a game. I could write several lines or a loop or maybe a variable argument method. I’ve used loops in tests in real systems. Your comment sounds like a context-free rule, which I tend to question.

    I agree on not using the const int (actually static const int, right).

    As for the score function taking into account extra rolls, several comments: 1. I wrote in the blog, this is happy path. 2. I also wrote in the blog that I had already posted an example with validation in Scala – specifically too many throws. 3. I would not allow the score card to have more than the allowed number of throws, so the loop is fine.

    And notice as I wrote the scoreAt method, I am able to score the entire game if I want.So we can agree to disagree.

    As for not using iterators, that is a side-effect of how I’ve stored the scores. In the original bowling kata, uncle bob only uses one array slot for a strike. I’ve done that as well. So if I use an iterator, I need to look ahead. Since for a std::vector an iterator is really just an int*, I can just use it along with indexes. But if look at the code, the frame can start on an even or odd index depending on the strikes. I know this is strange, I was just repeating form. I’ve done it this way and I’ve used 2 cells for all frames (other than the 10th frame) as well. It’s 6 of one half-dozen the other as far as I’m concerned. In any event, in this case if I used an iterator, I’d end up modifying the iterator by some amount. The iterator doesn’t express the solution any better than the index. I could have actually done that by setting the iterator ahead a number of indexes depending on the structure of the cells (which I did using an index instead of an iterator), but that’s taking knowledge of the underlying implementation of the iterator, which I think is a worse idea.

  3. Avatar
    Joseph Gutierrez 3 days later:

    @Bret,

    These Katas are great! The only thing that I haven’t seen from the bowling is the evolution of the scorer to an actual recognizer, like you would have for regexp.

    Anytime I see that I’m creating methods private or public that want to ask questions of internal state of my object, it starts to look like a code smell. I believe there is another object in there asking to be set free. Tell don’t ask.

    Thanks for the C++.

  4. Avatar
    L. 6 days later:

    @Brett:

    AFAIK, nothing in the C++ standard states that the iterator for std::vector is a bare pointer.

    @UncleBob:

    About the include order in C++, I personally usually include the lowest layers last (i.e. the STL last). If I did this the other way around (lowest layers first), it may hide the fact that some of my .h files don’t stand for themselves, e.g. do not include or when they should.

  5. Avatar
    L. 6 days later:

    Oops, I don’t know why,, but I thought the blog was written by Uncle Bob. Both comments were for Brett.

    And the last line should read : do not include <vector> or <list> when they should.

  6. Avatar
    Brett L. Schuchert 6 days later:

    @L – is that from DeathNote?

    I am not certain, but I do know that the access times (insertion, lookup) for vector are defined. Lookup, [], is O 1 (constant time), for example.

    Regarding include order, it turns out that using the latest version of CppUTest requires (in the test file), including or at least after any chance of things like , since it overloads global new/delete.

  7. Avatar
    L. 6 days later:

    No, I’m not DeathNote. I’m a long date follower of this blog but a new commenter, nice to meet you, Brett :)

    Thank you for the tip on CppUTest. I know things can get pretty nasty when you fiddle with the guts of a language.

    Thank you for this version of the Kata. Seeing some good C++ from time to time is refreshing.

    By the way, (it’s personal taste again) why not use boost::shared_ptr instead of a base pointer in the test class? You get nullity checking and reference counting almost for free.

  8. Avatar
    Brett L. Schuchert 7 days later:

    @L,

    I really like the boost library. I used it quite a bit when porting the projects for one of our Java classes to C++. However, I have no good reason for not using it in this project. Actually, I didn’t even consider it.

    All I have to do is update the list of directories to search for include files. I probably didn’t consider it because the takes care of dynamic allocation in the scorer and the only other place I use new is in a controlled environment, the test.

    But really, didn’t even consider it. Not exactly sure why. If I were to work on a real project, the boos library is the first thing I’d bring into the mix. I like it.

  9. Avatar
    dfo gold 27 days later:

    c++ is a difficult book, as i know

  10. Avatar
    gucci louis vuitton shoes about 1 month later:

    Welcome to Freshstyleshop, the hottest urban clothing site on the net! We offer great products from Gucci sneakers, prada sneakers, LV shoes, True Religion Jeans and many more! Our selection of products are always increasing for the fact that we have new items added weekly to our selection. All products on our site are already marked down 40-60% off retail price. Freshstyleshop also backs all its orders with a 110% satisfaction guarantee, making sure that our customers are left satisfied with the hottest products on the net.

  11. Avatar
    han 5 months later:

    If not, could you please send me the code so we can continue to play with it? Thanks.

  12. Avatar
    Technology Information 6 months later:

    Good information about this topic. I really very useful and helpfulness article. I tried to your tips is a very successful on the worked.

  13. Avatar
    cosplay 10 months later:

    Good information about this topic. I really very useful and helpfulness article. I tried to your tips is a very successful on the worked.

  14. Avatar
    cheap vps 10 months later:

    Files not ending with a blank line? Was that really necessary? I can copy the code into an editor as is (vi is my editor of choice), save it and go. Are you picking nits or is there something else you’re trying to get at?

    The global pollution of the namespace is a good point. For this little practice session I didn’t care. In fact, where I used it, I was silly to do so anyway as I used nested typedefs.

    I do not agree with your comment about the ctor. Auto-generated ctors lead to larger .o files and code on many compilers. As for the virtual dtor, I add that. I don’t work in embedded systems, so the addition of the vtable is not much of an issue. If I were working in an embedded system, I’d be a lot more picky about the use of virtual methods anywhere. But I’d still explicitly code both of them rather than let the compiler regenerate the code everywhere instances are constructed.cheap VPS

  15. Avatar
    Free Hosting With MYSQL 10 months later:

    Wow – these are absolutely fantastic. We love Creative Commons and thank you for putting Free Hosting With MYSQL

  16. Avatar
    branded shopping 10 months later:

    Thank you so much for your work on keeping the site together and keeping these flowing. branded shopping

  17. Avatar
    gucci mens 10 months later:

    Well , the view of the passage is totally correct gucci mens ,your details is really reasonable gucci belt for men and you guy give us valuable informative post, size11 gucci sneakers I totally agree the standpoint of upstairs. I often discount gucci jeans surfing on this forum classic gucci wallets when I m free and I find there are so much good information we can learn in this forum!

  18. Avatar
    supplynflshop 10 months later:

    so good post i like it china nfl jerseys

  19. Avatar
    gucci wallet 12 months later:

    gucci wallet, gucci wallets, mens gucci wallets, women gucci wallets.

  20. Avatar
    replica louis vuitton belts 12 months later:

    replica louis vuitton belts, replica hermes belts, replica hermes belt, Elegant replica louis vuitton belt, Fashion replica louis vuitton belts for men, replica hermes for men.

  21. Avatar
    Hermes belts 12 months later:

    Hermes belts, Elegant Hermes belt, Fashion Hermes belts for men, Hermes mens belt.

  22. Avatar
    chanel store about 1 year later:

    I like! Thank you

  23. Avatar
    jherdy49@yahoo.com about 1 year later:

    I personally have many Louis Vuitton and Gucci wallets, I can afford them, I don’t think I’m being conned and when I take it out of my pocket it looks way better than bringing out a shoddy ‘Bodyglove’ one. Personally and through my company, I donate thousands a year to charity. Now do you think I’m going to listen to anyone on how I spend the money that I earn? —-—-—-—-—— silks-road.com

  24. Avatar
    Pandora about 1 year later:

    it probably doesn’t deserve all of the build up that I just gave it, but I suspect that I’ll be writing more about this topic. There’s definitely more to discuss.

  25. Avatar
    Harrishcolin about 1 year later:

    Thank you for this nice post

    my blog: alpha male | how to run faster

  26. Avatar
    ost about 1 year later:

    Great stuff, worth reading. Thanks for sharing!

  27. Avatar
    Alix about 1 year later:

    Choose from 4pmp dumps training courses from best private training institutions and third level colleges in hyderabad, India. learnpipe.in includes reviews, special discounts, public course dates, elearning courses, web based courses, and many more training options. testking 70-293|testking 000-977|testking 642-611|testking 642-681|testking HP0-D07|testking JN0-331

  28. Avatar
    http://www.blacktowhiteiphone4.com about 1 year later:

    Want to buy the hotest white iphone 4 Conversion Kit? www.whiteiphone4.com will be your best online store. Don’t hesitate to buy the charming iphone 4 Conversion Kit!

  29. Avatar
    Silicone Molding about 1 year later:

    Mold making is the core business of Intertech (Taiwan). With world level technology, Intertech enjoys a very good reputation for making Injection Mold and Plastic Moldsfor their worldwide customers.

  30. Avatar
    coach outlet store locations about 1 year later:

    great writing so far on your blog

  31. Avatar
    puma about 1 year later:

    Shopping for Mens puma speed cat Big Yellow,These matter can be found in many sources. Department supplies may keep them as well as operation shoe locations. Different operation shoed chains will tender a few different shoes from each category of shoe fray. They may hold a line of soccer Puma shoes, operation abrasion and basketball styles. This ideal is a form right shoe that looks great with casual pants. Puma shoes onlinesale Mens Puma Speed Cat Big Yellow Shoes hot sale in Ottawa will give somebody the gamble to attire something that is classy and lively. The panache on the leather and the influence will bestow somebody with an excellent looking Puma shoes. This entry could be tattered with shorts, pants and jeans. Small ankle socks in red or colorless may help to produce a balanced look. A purchaser may find this sort in a footwear store or through an online retailer. In the sell for an open evaluate of the Mens Puma Speed Cat Big Gold Black Shoes? Get the absolute inside scrape and attrition now in our manual to the great puma eminent cat lo.

  32. Avatar
    Hermes belts about 1 year later:

    Hermes belts, Hermes belt, Hermes belts for men, Hermes mens belt, dupont lighter, dupont lighters, st dupont lighter, s.t. dupont lighters.

  33. Avatar
    LV belt about 1 year later:

    LV belt, LV belts, LV belts for men, LV Mens belts, louis vuitton mens wallets,gucci mens wallets,hermes mens wallets,prada mens wallets.

  34. Avatar
    Men’s belts about 1 year later:

    Men’s belts, LV men’s belts, Gucci men’s belts, Hermes men’s belts.

  35. Avatar
    Pittsburgh events about 1 year later:

    I am not certain, but I do know that the access times (insertion, lookup) for vector are defined. Lookup, [], is O 1 (constant time), for example.

    Regarding include order, it turns out that using the latest version of CppUTest requires (in the test file), including or at least after any chance of things like , since it overloads global new/delete.

  36. Avatar
    iPad to Mac Transfer about 1 year later:

    I really like this essay. Thank you for writing it so seriously. I want to recommend it for my friends strongly. iPad to Mac Transfer can help you transfer music, movie, photo, ePub, PDF, Audiobook, Podcast and TV Show from ipad to mac freely.

  37. Avatar
    iPhone SMS to Mac Backup about 1 year later:

    Would you like to banckup iphone SMS to mac, macBook, macbookPro as .txt files? Now a software iphone SMS to Mac Backup can help you to realize it.

  38. Avatar
    cable ties about 1 year later:

    Love this essay!

  39. Avatar
    dswehfhh about 1 year later:

    We are the professional clothes manufacturer and clothes supplier, so we manufacture kinds of custom clothes manufacturer. welcome you to come to our china clothes manufacturer and clothes factory.

  40. Avatar
    cheap true religion los angeles about 1 year later:

    hni

    Method of washing and maintenance of True Religion Jeans for cheapjeans 1,
  41. Avatar
    Bartender's Guide about 1 year later:

    Would you like to banckup iphone SMS to mac, macBook, macbookPro as .txt files? Now a software iphone SMS to Mac Backup can help you to realize it.

  42. Avatar
    dory about 1 year later:

    This is a good post. This post give truly quality information.I’m definitely going to look into it. Really very useful tips are provided here.thank you so much.Keep up the good works. Social Network

  43. Avatar
    http://www.tiffanyandcooutlet.net/ about 1 year later:

    Almost any situation--good or bad --is affected by the attitude we bring to. Adversity reveals genius; fortune conceals it. As fruit needs not only sunshine but cold nights and chilling showers to ripen it, so character needs not only joy but trial and difficulty to mellow it. Although the world is full of suffering, it is full also of the overcoming of it. tiffany and co outlet

  44. Avatar
    Seobaglyak about 1 year later:

    a Seobaglyak igazán éjszaka érzik elemükben magukat. Szinte ”kétlaki” életet élnek. A Seobaglyak éjszaka sokkal éberebbek, és agresszívabbak, olyannyira, hogy olyankor saját fajtársaikat tartják a legnagyobb ellenségeiknek.

  45. Avatar
    okey oyunu oyna about 1 year later:

    Thanks a lot for sharing this post.

    internette görüntülü olarak okey oyunu oyna, gerçek kisilerle tanis, turnuva heyecanini yasa.

  46. Avatar
    Hermes belts about 1 year later:

    ighest quality and cheap belts shop at Hermes belts store.

  47. Avatar
    Hermes belt about 1 year later:

    Highest quality and cheap belts shop at Hermes belt store.

  48. Avatar
    f350 leveling kit about 1 year later:

    wow.. good blog . thanks

  49. Avatar
    ford leveling kit about 1 year later:

    i love this website… got a fine ideas thanks you sir.

  50. Avatar
    leveling kit f250 about 1 year later:

    thanks for this post sir i lie it…

  51. Avatar
    f350 leveling kit about 1 year later:

    wonderful blog and informative ..thanks a lot.

  52. Avatar
    real estate advertising about 1 year later:

    wow very nice, i love this website… got a fine idea

  53. Avatar
    lose thigh about 1 year later:

    like the source code…

  54. Avatar
    commission predators about 1 year later:

    What a wonderful article! And are doing well on the whole, but their work also has shortcomings.

  55. Avatar
    Best Treadmills For Home about 1 year later:

    Thanks for this post since I am new to C++ and this will help me study.

  56. Avatar
    Jeremy Scott Panda about 1 year later:

    Australia’s benchmark S&P/ASX200 index rose 3 percent in early trading to 4,214 points, while New Zealand’s benchmark NZX50 was up almost 4 percent by midmorning. In Japan, the Nikkei 225 was up 1.4 percent to 9,073.37 in early trading. Adidas Panda Bear

  57. Avatar
    beats by dre store about 1 year later:

    while New Zealand’s benchmark NZX50 was up almost 4 percent high quality headphones new design headphones

  58. Avatar
    bagsupplyer about 1 year later:

    I really enjoy your articles. Very well written. Discount fashion women Coach Lowcut shoes from China for wholesale free shipping,more order,more discount

  59. Avatar
    Louboutins about 1 year later:

    asda s+dfa+9sd5fd666

  60. Avatar
    moncler about 1 year later:

    asdfsad f+9d68555444

  61. Avatar
    Christian about 1 year later:

    asas fd+-*+s+s+s+s

  62. Avatar
    Ashley Bowling about 1 year later:

    Abraham Lincoln reportedly said that, given eight hours to chop down a tree, he’d spend six sharpening his axe.

  63. Avatar
    <a href="http://www.airmaxbwltd.com/"> requin tn </a> over 2 years later:

    Avertissement consulter cet article représenter l’auteur nike tn , n’a rien à voir avec les chaussures Amoy réseau. Les déclarations d’origine et le papier, les opinions restent juge neutre, ne contient pas le contenu de l’exactitude, la fiabilité ou l’exhaustivité de toute garantie expresse ou implicite. Le lecteur est pour référence seulement, et d’accepter la pleine responsabilité de vos propres basket tn . Nike intelligemment éviter la pression lucratif U. S. entreprise de chaussures Nike (Nike) du premier trimestre des revenus et des prix considérablement augmenté, évitant habilement la pression de marge. La société a déclaré aujourd’hui à propos d’entrer dans les fêtes de Noël requin tn , que ses concurrents dans la même position est très optimiste.

  64. Avatar
    bladeless fans over 2 years later:

    C++ Bowling Kata Result 63 good post91

  65. Avatar
    louboutin sales over 2 years later:

    C++ Bowling Kata Result 64 hoo,good article!!I like the post!180

  66. Avatar
    Silicone Molding (100% made in Taiwan) over 3 years later:

    With more than 20 years of experience, Intertech provides an extensive integrated operational ability from design to production of molds 100% made in Taiwan. Additional to our own mold making factory, we also cooperate with our team vendors to form a very strong working force in Taiwan.

    For the overseas market, we work very closely with local representatives in order to take care of the technical communication and after-sales service to our customers. We also participate in the EUROMOLD & FAKUMA exhibitions and meet our customers every year in Europe. By concentrating on mold “niche markets”, we play a very useful mold maker role from the Far East whenever customers want to develop their new projects. We provide services from A to Z to our customers on a very economic cost and effect basis.

  67. Avatar
    Plastic Injection Mold (100% made in Taiwan) over 3 years later:

    With more than 20 years of experience, Intertech provides an extensive integrated operational ability from design to production of molds 100% made in Taiwan. Additional to our own mold making factory, we also cooperate with our team vendors to form a very strong working force in Taiwan.

    For the overseas market, we work very closely with local representatives in order to take care of the technical communication and after-sales service to our customers. We also participate in the EUROMOLD & FAKUMA exhibitions and meet our customers every year in Europe. By concentrating on mold “niche markets”, we play a very useful mold maker role from the Far East whenever customers want to develop their new projects. We provide services from A to Z to our customers on a very economic cost and effect basis.

  68. Avatar
    hermes sellier kelly bag over 3 years later:

    Each famous fashion house, whether it is Hermes or Chanel or Prada etc?

  69. Avatar
    cosplay wigs over 3 years later:

    http://www.outfitscosplay.com/cosplay-catalog/tales-of-the-abyss-cosplay Deluxe Tales of The Abyss Cosplay Costumes for Sale.Find your favorite characters and cosplay outfits from all the popular anime and games.

Comments